@@ -166,103 +166,13 @@ static std::unique_ptr<Writer> createWriter(const CopyConfig &Config,
166
166
}
167
167
}
168
168
169
- template <class ELFT >
170
- static Expected<ArrayRef<uint8_t >>
171
- findBuildID (const CopyConfig &Config, const object::ELFFile<ELFT> &In) {
172
- auto PhdrsOrErr = In.program_headers ();
173
- if (auto Err = PhdrsOrErr.takeError ())
174
- return createFileError (Config.InputFilename , std::move (Err));
175
-
176
- for (const auto &Phdr : *PhdrsOrErr) {
177
- if (Phdr.p_type != PT_NOTE)
178
- continue ;
179
- Error Err = Error::success ();
180
- for (auto Note : In.notes (Phdr, Err))
181
- if (Note.getType () == NT_GNU_BUILD_ID && Note.getName () == ELF_NOTE_GNU)
182
- return Note.getDesc ();
183
- if (Err)
184
- return createFileError (Config.InputFilename , std::move (Err));
185
- }
186
-
187
- return createFileError (Config.InputFilename ,
188
- createStringError (llvm::errc::invalid_argument,
189
- " could not find build ID" ));
190
- }
191
-
192
- static Expected<ArrayRef<uint8_t >>
193
- findBuildID (const CopyConfig &Config, const object::ELFObjectFileBase &In) {
194
- if (auto *O = dyn_cast<ELFObjectFile<ELF32LE>>(&In))
195
- return findBuildID (Config, O->getELFFile ());
196
- else if (auto *O = dyn_cast<ELFObjectFile<ELF64LE>>(&In))
197
- return findBuildID (Config, O->getELFFile ());
198
- else if (auto *O = dyn_cast<ELFObjectFile<ELF32BE>>(&In))
199
- return findBuildID (Config, O->getELFFile ());
200
- else if (auto *O = dyn_cast<ELFObjectFile<ELF64BE>>(&In))
201
- return findBuildID (Config, O->getELFFile ());
202
-
203
- llvm_unreachable (" Bad file format" );
204
- }
205
-
206
169
template <class ... Ts>
207
170
static Error makeStringError (std::error_code EC, const Twine &Msg,
208
171
Ts &&... Args) {
209
172
std::string FullMsg = (EC.message () + " : " + Msg).str ();
210
173
return createStringError (EC, FullMsg.c_str (), std::forward<Ts>(Args)...);
211
174
}
212
175
213
- #define MODEL_8 " %%%%%%%%"
214
- #define MODEL_16 MODEL_8 MODEL_8
215
- #define MODEL_32 (MODEL_16 MODEL_16)
216
-
217
- static Error linkToBuildIdDir (const CopyConfig &Config, StringRef ToLink,
218
- StringRef Suffix,
219
- ArrayRef<uint8_t > BuildIdBytes) {
220
- SmallString<128 > Path = Config.BuildIdLinkDir ;
221
- sys::path::append (Path, llvm::toHex (BuildIdBytes[0 ], /* LowerCase*/ true ));
222
- if (auto EC = sys::fs::create_directories (Path))
223
- return createFileError (
224
- Path.str (),
225
- makeStringError (EC, " cannot create build ID link directory" ));
226
-
227
- sys::path::append (Path,
228
- llvm::toHex (BuildIdBytes.slice (1 ), /* LowerCase*/ true ));
229
- Path += Suffix;
230
- SmallString<128 > TmpPath;
231
- // create_hard_link races so we need to link to a temporary path but
232
- // we want to make sure that we choose a filename that does not exist.
233
- // By using 32 model characters we get 128-bits of entropy. It is
234
- // unlikely that this string has ever existed before much less exists
235
- // on this disk or in the current working directory.
236
- // Additionally we prepend the original Path for debugging but also
237
- // because it ensures that we're linking within a directory on the same
238
- // partition on the same device which is critical. It has the added
239
- // win of yet further decreasing the odds of a conflict.
240
- sys::fs::createUniquePath (Twine (Path) + " -" + MODEL_32 + " .tmp" , TmpPath,
241
- /* MakeAbsolute*/ false );
242
- if (auto EC = sys::fs::create_hard_link (ToLink, TmpPath)) {
243
- Path.push_back (' \0 ' );
244
- return makeStringError (EC, " cannot link '%s' to '%s'" , ToLink.data (),
245
- Path.data ());
246
- }
247
- // We then atomically rename the link into place which will just move the
248
- // link. If rename fails something is more seriously wrong so just return
249
- // an error.
250
- if (auto EC = sys::fs::rename (TmpPath, Path)) {
251
- Path.push_back (' \0 ' );
252
- return makeStringError (EC, " cannot link '%s' to '%s'" , ToLink.data (),
253
- Path.data ());
254
- }
255
- // If `Path` was already a hard-link to the same underlying file then the
256
- // temp file will be left so we need to remove it. Remove will not cause
257
- // an error by default if the file is already gone so just blindly remove
258
- // it rather than checking.
259
- if (auto EC = sys::fs::remove (TmpPath)) {
260
- TmpPath.push_back (' \0 ' );
261
- return makeStringError (EC, " could not remove '%s'" , TmpPath.data ());
262
- }
263
- return Error::success ();
264
- }
265
-
266
176
static Error splitDWOToFile (const CopyConfig &Config, const Reader &Reader,
267
177
StringRef File, ElfType OutputElfType) {
268
178
Expected<std::unique_ptr<Object>> DWOFile = Reader.create (false );
@@ -828,37 +738,12 @@ Error executeObjcopyOnBinary(const CopyConfig &Config,
828
738
const ElfType OutputElfType =
829
739
Config.OutputArch ? getOutputElfType (Config.OutputArch .getValue ())
830
740
: getOutputElfType (In);
831
- ArrayRef<uint8_t > BuildIdBytes;
832
-
833
- if (!Config.BuildIdLinkDir .empty ()) {
834
- auto BuildIdBytesOrErr = findBuildID (Config, In);
835
- if (auto E = BuildIdBytesOrErr.takeError ())
836
- return E;
837
- BuildIdBytes = *BuildIdBytesOrErr;
838
-
839
- if (BuildIdBytes.size () < 2 )
840
- return createFileError (
841
- Config.InputFilename ,
842
- createStringError (object_error::parse_failed,
843
- " build ID is smaller than two bytes" ));
844
- }
845
-
846
- if (!Config.BuildIdLinkDir .empty () && Config.BuildIdLinkInput )
847
- if (Error E =
848
- linkToBuildIdDir (Config, Config.InputFilename ,
849
- Config.BuildIdLinkInput .getValue (), BuildIdBytes))
850
- return E;
851
741
852
742
if (Error E = handleArgs (Config, **Obj, Reader, OutputElfType))
853
743
return createFileError (Config.InputFilename , std::move (E));
854
744
855
745
if (Error E = writeOutput (Config, **Obj, Out, OutputElfType))
856
746
return createFileError (Config.InputFilename , std::move (E));
857
- if (!Config.BuildIdLinkDir .empty () && Config.BuildIdLinkOutput )
858
- if (Error E =
859
- linkToBuildIdDir (Config, Config.OutputFilename ,
860
- Config.BuildIdLinkOutput .getValue (), BuildIdBytes))
861
- return createFileError (Config.OutputFilename , std::move (E));
862
747
863
748
return Error::success ();
864
749
}
0 commit comments