LLVM 20.0.0git
WasmObjcopy.cpp
Go to the documentation of this file.
1//===- WasmObjcopy.cpp ----------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "WasmObject.h"
11#include "WasmReader.h"
12#include "WasmWriter.h"
14#include "llvm/Support/Errc.h"
16
17namespace llvm {
18namespace objcopy {
19namespace wasm {
20
21using namespace object;
22using SectionPred = std::function<bool(const Section &Sec)>;
23
24static bool isDebugSection(const Section &Sec) {
25 return Sec.Name.starts_with(".debug") || Sec.Name.starts_with("reloc..debug");
26}
27
28static bool isLinkerSection(const Section &Sec) {
29 return Sec.Name.starts_with("reloc.") || Sec.Name == "linking";
30}
31
32static bool isNameSection(const Section &Sec) { return Sec.Name == "name"; }
33
34// Sections which are known to be "comments" or informational and do not affect
35// program semantics.
36static bool isCommentSection(const Section &Sec) {
37 return Sec.Name == "producers";
38}
39
40static Error dumpSectionToFile(StringRef SecName, StringRef Filename,
41 Object &Obj) {
42 for (const Section &Sec : Obj.Sections) {
43 if (Sec.Name == SecName) {
44 ArrayRef<uint8_t> Contents = Sec.Contents;
46 FileOutputBuffer::create(Filename, Contents.size());
47 if (!BufferOrErr)
48 return BufferOrErr.takeError();
49 std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufferOrErr);
50 std::copy(Contents.begin(), Contents.end(), Buf->getBufferStart());
51 if (Error E = Buf->commit())
52 return E;
53 return Error::success();
54 }
55 }
56 return createStringError(errc::invalid_argument, "section '%s' not found",
57 SecName.str().c_str());
58}
59
60static void removeSections(const CommonConfig &Config, Object &Obj) {
61 SectionPred RemovePred = [](const Section &) { return false; };
62
63 // Explicitly-requested sections.
64 if (!Config.ToRemove.empty()) {
65 RemovePred = [&Config](const Section &Sec) {
66 return Config.ToRemove.matches(Sec.Name);
67 };
68 }
69
70 if (Config.StripDebug) {
71 RemovePred = [RemovePred](const Section &Sec) {
72 return RemovePred(Sec) || isDebugSection(Sec);
73 };
74 }
75
76 if (Config.StripAll) {
77 RemovePred = [RemovePred](const Section &Sec) {
78 return RemovePred(Sec) || isDebugSection(Sec) || isLinkerSection(Sec) ||
80 };
81 }
82
83 if (Config.OnlyKeepDebug) {
84 RemovePred = [&Config](const Section &Sec) {
85 // Keep debug sections, unless explicitly requested to remove.
86 // Remove everything else, including known sections.
87 return Config.ToRemove.matches(Sec.Name) || !isDebugSection(Sec);
88 };
89 }
90
91 if (!Config.OnlySection.empty()) {
92 RemovePred = [&Config](const Section &Sec) {
93 // Explicitly keep these sections regardless of previous removes.
94 // Remove everything else, inluding known sections.
95 return !Config.OnlySection.matches(Sec.Name);
96 };
97 }
98
99 if (!Config.KeepSection.empty()) {
100 RemovePred = [&Config, RemovePred](const Section &Sec) {
101 // Explicitly keep these sections regardless of previous removes.
102 if (Config.KeepSection.matches(Sec.Name))
103 return false;
104 // Otherwise defer to RemovePred.
105 return RemovePred(Sec);
106 };
107 }
108
109 Obj.removeSections(RemovePred);
110}
111
113 // Only support AddSection, DumpSection, RemoveSection for now.
114 for (StringRef Flag : Config.DumpSection) {
115 StringRef SecName;
116 StringRef FileName;
117 std::tie(SecName, FileName) = Flag.split("=");
118 if (Error E = dumpSectionToFile(SecName, FileName, Obj))
119 return createFileError(FileName, std::move(E));
120 }
121
123
124 for (const NewSectionInfo &NewSection : Config.AddSection) {
125 Section Sec;
127 Sec.Name = NewSection.SectionName;
128
129 llvm::StringRef InputData =
130 llvm::StringRef(NewSection.SectionData->getBufferStart(),
131 NewSection.SectionData->getBufferSize());
132 std::unique_ptr<MemoryBuffer> BufferCopy = MemoryBuffer::getMemBufferCopy(
133 InputData, NewSection.SectionData->getBufferIdentifier());
135 reinterpret_cast<const uint8_t *>(BufferCopy->getBufferStart()),
136 BufferCopy->getBufferSize());
137
138 Obj.addSectionWithOwnedContents(Sec, std::move(BufferCopy));
139 }
140
141 return Error::success();
142}
143
146 Reader TheReader(In);
147 Expected<std::unique_ptr<Object>> ObjOrErr = TheReader.create();
148 if (!ObjOrErr)
149 return createFileError(Config.InputFilename, ObjOrErr.takeError());
150 Object *Obj = ObjOrErr->get();
151 assert(Obj && "Unable to deserialize Wasm object");
152 if (Error E = handleArgs(Config, *Obj))
153 return E;
154 Writer TheWriter(*Obj, Out);
155 if (Error E = TheWriter.write())
156 return createFileError(Config.OutputFilename, std::move(E));
157 return Error::success();
158}
159
160} // end namespace wasm
161} // end namespace objcopy
162} // end namespace llvm
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
RelaxConfig Config
Definition: ELF_riscv.cpp:506
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
iterator end() const
Definition: ArrayRef.h:157
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:168
iterator begin() const
Definition: ArrayRef.h:156
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:337
Tagged union holding either a T or a Error.
Definition: Error.h:481
Error takeError()
Take ownership of the stored error.
Definition: Error.h:608
reference get()
Returns a reference to the stored T value.
Definition: Error.h:578
static Expected< std::unique_ptr< FileOutputBuffer > > create(StringRef FilePath, size_t Size, unsigned Flags=0)
Factory method to create an OutputBuffer object which manages a read/write buffer of the specified si...
static std::unique_ptr< MemoryBuffer > getMemBufferCopy(StringRef InputData, const Twine &BufferName="")
Open the specified memory range as a MemoryBuffer, copying the contents and taking ownership of it.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:229
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:265
Expected< std::unique_ptr< Object > > create() const
Definition: WasmReader.cpp:18
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
static bool isCommentSection(const Section &Sec)
Definition: WasmObjcopy.cpp:36
static void removeSections(const CommonConfig &Config, Object &Obj)
Definition: WasmObjcopy.cpp:60
static Error dumpSectionToFile(StringRef SecName, StringRef Filename, Object &Obj)
Definition: WasmObjcopy.cpp:40
static Error handleArgs(const CommonConfig &Config, Object &Obj)
static bool isDebugSection(const Section &Sec)
Definition: WasmObjcopy.cpp:24
std::function< bool(const Section &Sec)> SectionPred
Definition: WasmObjcopy.cpp:22
static bool isNameSection(const Section &Sec)
Definition: WasmObjcopy.cpp:32
static bool isLinkerSection(const Section &Sec)
Definition: WasmObjcopy.cpp:28
Error executeObjcopyOnBinary(const CommonConfig &Config, const WasmConfig &, object::WasmObjectFile &In, raw_ostream &Out)
Apply the transformations described by Config and WasmConfig to In and writes the result into Out.
@ WASM_SEC_CUSTOM
Definition: Wasm.h:35
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
Definition: Error.h:1385
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1291
std::shared_ptr< MemoryBuffer > SectionData
Definition: CommonConfig.h:203
std::vector< Section > Sections
Definition: WasmObject.h:34
void addSectionWithOwnedContents(Section NewSection, std::unique_ptr< MemoryBuffer > &&Content)
Definition: WasmObject.cpp:18
void removeSections(function_ref< bool(const Section &)> ToRemove)
Definition: WasmObject.cpp:24
ArrayRef< uint8_t > Contents
Definition: WasmObject.h:28