Skip to content

Commit 6f151fb

Browse files
committed
[llvm-ar][Object][COFF] Compute UseECMap in computeMemberData.
Compute it instead of requiring caller to pass it to, which is inconvenient for llvm-ar.
1 parent d8b6935 commit 6f151fb

File tree

5 files changed

+118
-14
lines changed

5 files changed

+118
-14
lines changed

llvm/include/llvm/Object/ArchiveWriter.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ enum class SymtabWritingMode {
5151
Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
5252
SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
5353
bool Deterministic, bool Thin,
54-
std::unique_ptr<MemoryBuffer> OldArchiveBuf = nullptr,
55-
bool IsEC = false);
54+
std::unique_ptr<MemoryBuffer> OldArchiveBuf = nullptr);
5655

5756
// writeArchiveToBuffer is similar to writeArchive but returns the Archive in a
5857
// buffer instead of writing it out to a file.

llvm/lib/Object/ArchiveWriter.cpp

+29-6
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ using namespace llvm;
4848
using namespace llvm::object;
4949

5050
struct SymMap {
51-
bool UseECMap;
51+
bool UseECMap = false;
5252
std::map<std::string, uint16_t> Map;
5353
std::map<std::string, uint16_t> ECMap;
5454
};
@@ -678,6 +678,25 @@ static bool isECObject(object::SymbolicFile &Obj) {
678678
return false;
679679
}
680680

681+
static bool useECMap(object::SymbolicFile &Obj) {
682+
if (Obj.isCOFF())
683+
return COFF::isAnyArm64(cast<COFFObjectFile>(&Obj)->getMachine());
684+
685+
if (Obj.isCOFFImportFile())
686+
return COFF::isAnyArm64(cast<COFFImportFile>(&Obj)->getMachine());
687+
688+
if (Obj.isIR()) {
689+
Expected<std::string> TripleStr =
690+
getBitcodeTargetTriple(Obj.getMemoryBufferRef());
691+
if (!TripleStr)
692+
return false;
693+
Triple T(*TripleStr);
694+
return T.getArch() == Triple::aarch64;
695+
}
696+
697+
return false;
698+
}
699+
681700
bool isImportDescriptor(StringRef Name) {
682701
return Name.starts_with(ImportDescriptorPrefix) ||
683702
Name == StringRef{NullImportDescriptorSymbolName} ||
@@ -803,6 +822,11 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
803822
getSymbolicFile(M.Buf->getMemBufferRef(), Context);
804823
if (!SymFileOrErr)
805824
return createFileError(M.MemberName, SymFileOrErr.takeError());
825+
826+
// Use EC map if any member is ARM64 COFF file.
827+
if (Kind == Archive::K_COFF && !SymMap->UseECMap && *SymFileOrErr)
828+
SymMap->UseECMap = useECMap(**SymFileOrErr);
829+
806830
SymFiles.push_back(std::move(*SymFileOrErr));
807831
}
808832
}
@@ -957,7 +981,7 @@ static Error writeArchiveToStream(raw_ostream &Out,
957981
ArrayRef<NewArchiveMember> NewMembers,
958982
SymtabWritingMode WriteSymtab,
959983
object::Archive::Kind Kind,
960-
bool Deterministic, bool Thin, bool IsEC) {
984+
bool Deterministic, bool Thin) {
961985
assert((!Thin || !isBSDLike(Kind)) && "Only the gnu format has a thin mode");
962986

963987
SmallString<0> SymNamesBuf;
@@ -977,7 +1001,6 @@ static Error writeArchiveToStream(raw_ostream &Out,
9771001
// reference to it, thus SymbolicFile should be destroyed first.
9781002
LLVMContext Context;
9791003

980-
SymMap.UseECMap = IsEC;
9811004
Expected<std::vector<MemberData>> DataOrErr = computeMemberData(
9821005
StringTable, SymNames, Kind, Thin, Deterministic, WriteSymtab,
9831006
isCOFFArchive(Kind) ? &SymMap : nullptr, Context, NewMembers);
@@ -1226,15 +1249,15 @@ static Error writeArchiveToStream(raw_ostream &Out,
12261249
Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
12271250
SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
12281251
bool Deterministic, bool Thin,
1229-
std::unique_ptr<MemoryBuffer> OldArchiveBuf, bool IsEC) {
1252+
std::unique_ptr<MemoryBuffer> OldArchiveBuf) {
12301253
Expected<sys::fs::TempFile> Temp =
12311254
sys::fs::TempFile::create(ArcName + ".temp-archive-%%%%%%%.a");
12321255
if (!Temp)
12331256
return Temp.takeError();
12341257
raw_fd_ostream Out(Temp->FD, false);
12351258

12361259
if (Error E = writeArchiveToStream(Out, NewMembers, WriteSymtab, Kind,
1237-
Deterministic, Thin, IsEC)) {
1260+
Deterministic, Thin)) {
12381261
if (Error DiscardError = Temp->discard())
12391262
return joinErrors(std::move(E), std::move(DiscardError));
12401263
return E;
@@ -1263,7 +1286,7 @@ writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers,
12631286
raw_svector_ostream ArchiveStream(ArchiveBufferVector);
12641287

12651288
if (Error E = writeArchiveToStream(ArchiveStream, NewMembers, WriteSymtab,
1266-
Kind, Deterministic, Thin, false))
1289+
Kind, Deterministic, Thin))
12671290
return std::move(E);
12681291

12691292
return std::make_unique<SmallVectorMemoryBuffer>(

llvm/lib/Object/COFFImportFile.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -711,8 +711,7 @@ Error writeImportLibrary(StringRef ImportName, StringRef Path,
711711

712712
return writeArchive(Path, Members, SymtabWritingMode::NormalSymtab,
713713
object::Archive::K_COFF,
714-
/*Deterministic*/ true, /*Thin*/ false,
715-
/*OldArchiveBuf*/ nullptr, isArm64EC(Machine));
714+
/*Deterministic*/ true, /*Thin*/ false);
716715
}
717716

718717
} // namespace object

llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -507,10 +507,10 @@ int llvm::libDriverMain(ArrayRef<const char *> ArgsArr) {
507507
std::reverse(Members.begin(), Members.end());
508508

509509
bool Thin = Args.hasArg(OPT_llvmlibthin);
510-
if (Error E = writeArchive(
511-
OutputPath, Members, SymtabWritingMode::NormalSymtab,
512-
Thin ? object::Archive::K_GNU : object::Archive::K_COFF,
513-
/*Deterministic=*/true, Thin, nullptr, COFF::isArm64EC(LibMachine))) {
510+
if (Error E =
511+
writeArchive(OutputPath, Members, SymtabWritingMode::NormalSymtab,
512+
Thin ? object::Archive::K_GNU : object::Archive::K_COFF,
513+
/*Deterministic=*/true, Thin)) {
514514
handleAllErrors(std::move(E), [&](const ErrorInfoBase &EI) {
515515
llvm::errs() << OutputPath << ": " << EI.message() << "\n";
516516
});
+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
## Test that ECSYMBOLS section is created when ARM64EC is used.
2+
3+
# RUN: yaml2obj %s -o %t.arm64ec.obj -DMACHINE=IMAGE_FILE_MACHINE_ARM64EC
4+
# RUN: yaml2obj %s -o %t.arm64.obj -DMACHINE=IMAGE_FILE_MACHINE_ARM64
5+
# RUN: yaml2obj %s -o %t.amd64.obj -DMACHINE=IMAGE_FILE_MACHINE_AMD64
6+
7+
## Create ARM64EC archive
8+
# RUN: rm -f %t.a
9+
# RUN: llvm-ar crs %t.a %t.arm64ec.obj
10+
# RUN: llvm-nm --print-armap %t.a | FileCheck --check-prefixes=NOMAP,ECMAP %s
11+
12+
## Add ARM64 object to the archive
13+
# RUN: llvm-ar rs %t.a %t.arm64.obj
14+
# RUN: llvm-nm --print-armap %t.a | FileCheck --check-prefixes=MAP,ECMAP %s
15+
16+
## Create ARM64 archive
17+
# RUN: rm -f %t.a
18+
# RUN: llvm-ar crs %t.a %t.arm64.obj
19+
# RUN: llvm-nm --print-armap %t.a | FileCheck --check-prefixes=MAP,NOECMAP %s
20+
21+
# Add ARM64EC object to the archive
22+
# RUN: llvm-ar rs %t.a %t.arm64ec.obj
23+
# RUN: llvm-nm --print-armap %t.a | FileCheck --check-prefixes=MAP,ECMAP %s
24+
25+
## Create mixed archive
26+
# RUN: rm -f %t.a
27+
# RUN: llvm-ar crs %t.a %t.arm64ec.obj %t.arm64.obj
28+
# RUN: llvm-nm --print-armap %t.a | FileCheck --check-prefixes=MAP,ECMAP %s
29+
30+
## Create mixed archive
31+
# RUN: rm -f %t.a
32+
# RUN: llvm-ar crs %t.a %t.amd64.obj %t.arm64.obj
33+
# RUN: llvm-nm --print-armap %t.a | FileCheck --check-prefixes=MAP,AMDECMAP %s
34+
35+
# MAP: Archive map
36+
# MAP-NEXT: a in ecsymbols.yaml.tmp.arm64.obj
37+
# MAP-NEXT: b in ecsymbols.yaml.tmp.arm64.obj
38+
# MAP-NEXT: c in ecsymbols.yaml.tmp.arm64.obj
39+
# MAP-EMPTY:
40+
# NOMAP-NOT: Archive map
41+
42+
# ECMAP: Archive EC map
43+
# ECMAP-NEXT: a in ecsymbols.yaml.tmp.arm64ec.obj
44+
# ECMAP-NEXT: b in ecsymbols.yaml.tmp.arm64ec.obj
45+
# ECMAP-NEXT: c in ecsymbols.yaml.tmp.arm64ec.obj
46+
# ECMAP-EMPTY:
47+
# NOECMAP-NOT: Archive EC map
48+
49+
# AMDECMAP: Archive EC map
50+
# AMDECMAP-NEXT: a in ecsymbols.yaml.tmp.amd64.obj
51+
# AMDECMAP-NEXT: b in ecsymbols.yaml.tmp.amd64.obj
52+
# AMDECMAP-NEXT: c in ecsymbols.yaml.tmp.amd64.obj
53+
# ECMAP-EMPTY:
54+
55+
--- !COFF
56+
header:
57+
Machine: [[MACHINE]]
58+
Characteristics: [ ]
59+
sections:
60+
- Name: .text
61+
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
62+
Alignment: 4
63+
SectionData: ''
64+
symbols:
65+
- Name: b
66+
Value: 0
67+
SectionNumber: 1
68+
SimpleType: IMAGE_SYM_TYPE_NULL
69+
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
70+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
71+
- Name: c
72+
Value: 0
73+
SectionNumber: 1
74+
SimpleType: IMAGE_SYM_TYPE_NULL
75+
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
76+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
77+
- Name: a
78+
Value: 0
79+
SectionNumber: 1
80+
SimpleType: IMAGE_SYM_TYPE_NULL
81+
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
82+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
83+
...

0 commit comments

Comments
 (0)