mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
Overwrite instead of adding to archives when creating them in mri scripts.
This matches the behavior of GNU ar and also makes it easier to implemnt support for the addlib command. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220336 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2d20cb2892
commit
e539932aad
@ -14,5 +14,23 @@
|
||||
; CHECK-NEXT: 0000000000000000 T main
|
||||
; CHECK-NEXT: U puts
|
||||
|
||||
; Now test that CREATE overwrites an existing file.
|
||||
; RUN: echo create %t.a > %t2.mri
|
||||
; RUN: echo addmod %p/Inputs/trivial-object-test2.elf-x86-64 >> %t2.mri
|
||||
; RUN: echo save >> %t2.mri
|
||||
; RUN: echo end >> %t2.mri
|
||||
|
||||
; RUN: llvm-ar -M < %t2.mri
|
||||
; RUN: llvm-nm -M %t.a | FileCheck --check-prefix=NEW %s
|
||||
|
||||
; NEW: Archive map
|
||||
; NEW-NEXT: foo in trivial-object-test2.elf-x86-64
|
||||
; NEW-NEXT: main in trivial-object-test2.elf-x86-64
|
||||
|
||||
; NEW: trivial-object-test2.elf-x86-64:
|
||||
; NEW-NEXT: 0000000000000000 t bar
|
||||
; NEW-NEXT: 0000000000000006 T foo
|
||||
; NEW-NEXT: 0000000000000016 T main
|
||||
|
||||
; line_iterator is incompatible to CRLF.
|
||||
; REQUIRES: shell
|
||||
|
@ -176,59 +176,7 @@ static void getMembers() {
|
||||
Members.push_back(Arg);
|
||||
}
|
||||
|
||||
namespace {
|
||||
enum class MRICommand { AddMod, Create, Save, End, Invalid };
|
||||
}
|
||||
|
||||
static std::vector<std::string> MRIMembers;
|
||||
static ArchiveOperation parseMRIScript() {
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>> Buf = MemoryBuffer::getSTDIN();
|
||||
failIfError(Buf.getError());
|
||||
const MemoryBuffer &Ref = *Buf.get();
|
||||
bool Saved = false;
|
||||
|
||||
for (line_iterator I(Ref, /*SkipBlanks*/ true, ';'), E; I != E; ++I) {
|
||||
StringRef Line = *I;
|
||||
StringRef CommandStr, Rest;
|
||||
std::tie(CommandStr, Rest) = Line.split(' ');
|
||||
auto Command = StringSwitch<MRICommand>(CommandStr.lower())
|
||||
.Case("addmod", MRICommand::AddMod)
|
||||
.Case("create", MRICommand::Create)
|
||||
.Case("save", MRICommand::Save)
|
||||
.Case("end", MRICommand::End)
|
||||
.Default(MRICommand::Invalid);
|
||||
|
||||
switch (Command) {
|
||||
case MRICommand::AddMod:
|
||||
MRIMembers.push_back(Rest);
|
||||
break;
|
||||
case MRICommand::Create:
|
||||
Create = true;
|
||||
if (!ArchiveName.empty())
|
||||
fail("Editing multiple archives not supported");
|
||||
if (Saved)
|
||||
fail("File already saved");
|
||||
ArchiveName = Rest;
|
||||
break;
|
||||
case MRICommand::Save:
|
||||
Saved = true;
|
||||
break;
|
||||
case MRICommand::End:
|
||||
break;
|
||||
case MRICommand::Invalid:
|
||||
fail("Unknown command: " + CommandStr);
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing to do if not saved.
|
||||
if (!Saved)
|
||||
exit(0);
|
||||
|
||||
for (auto &M : MRIMembers)
|
||||
Members.push_back(M);
|
||||
|
||||
return ReplaceOrInsert;
|
||||
}
|
||||
static void runMRIScript();
|
||||
|
||||
// Parse the command line options as presented and return the operation
|
||||
// specified. Process all modifiers and check to make sure that constraints on
|
||||
@ -237,7 +185,7 @@ static ArchiveOperation parseCommandLine() {
|
||||
if (MRI) {
|
||||
if (!RestOfArgs.empty())
|
||||
fail("Cannot mix -M and other options");
|
||||
return parseMRIScript();
|
||||
runMRIScript();
|
||||
}
|
||||
|
||||
getOptions();
|
||||
@ -805,8 +753,9 @@ writeSymbolTable(raw_fd_ostream &Out, ArrayRef<NewArchiveIterator> Members,
|
||||
Out.seek(Pos);
|
||||
}
|
||||
|
||||
static void performWriteOperation(ArchiveOperation Operation,
|
||||
object::Archive *OldArchive) {
|
||||
static void
|
||||
performWriteOperation(ArchiveOperation Operation, object::Archive *OldArchive,
|
||||
std::vector<NewArchiveIterator> &NewMembers) {
|
||||
SmallString<128> TmpArchive;
|
||||
failIfError(sys::fs::createUniqueFile(ArchiveName + ".temp-archive-%%%%%%%.a",
|
||||
TmpArchiveFD, TmpArchive));
|
||||
@ -816,9 +765,6 @@ static void performWriteOperation(ArchiveOperation Operation,
|
||||
raw_fd_ostream &Out = Output.os();
|
||||
Out << "!<arch>\n";
|
||||
|
||||
std::vector<NewArchiveIterator> NewMembers =
|
||||
computeNewArchiveMembers(Operation, OldArchive);
|
||||
|
||||
std::vector<std::pair<unsigned, unsigned> > MemberOffsetRefs;
|
||||
|
||||
std::vector<std::unique_ptr<MemoryBuffer>> Buffers;
|
||||
@ -914,6 +860,18 @@ static void performWriteOperation(ArchiveOperation Operation,
|
||||
TemporaryOutput = nullptr;
|
||||
}
|
||||
|
||||
static void
|
||||
performWriteOperation(ArchiveOperation Operation, object::Archive *OldArchive,
|
||||
std::vector<NewArchiveIterator> *NewMembersP) {
|
||||
if (NewMembersP) {
|
||||
performWriteOperation(Operation, OldArchive, *NewMembersP);
|
||||
return;
|
||||
}
|
||||
std::vector<NewArchiveIterator> NewMembers =
|
||||
computeNewArchiveMembers(Operation, OldArchive);
|
||||
performWriteOperation(Operation, OldArchive, NewMembers);
|
||||
}
|
||||
|
||||
static void createSymbolTable(object::Archive *OldArchive) {
|
||||
// When an archive is created or modified, if the s option is given, the
|
||||
// resulting archive will have a current symbol table. If the S option
|
||||
@ -924,11 +882,12 @@ static void createSymbolTable(object::Archive *OldArchive) {
|
||||
if (OldArchive->hasSymbolTable())
|
||||
return;
|
||||
|
||||
performWriteOperation(CreateSymTab, OldArchive);
|
||||
performWriteOperation(CreateSymTab, OldArchive, nullptr);
|
||||
}
|
||||
|
||||
static void performOperation(ArchiveOperation Operation,
|
||||
object::Archive *OldArchive) {
|
||||
object::Archive *OldArchive,
|
||||
std::vector<NewArchiveIterator> *NewMembers) {
|
||||
switch (Operation) {
|
||||
case Print:
|
||||
case DisplayTable:
|
||||
@ -940,7 +899,7 @@ static void performOperation(ArchiveOperation Operation,
|
||||
case Move:
|
||||
case QuickAppend:
|
||||
case ReplaceOrInsert:
|
||||
performWriteOperation(Operation, OldArchive);
|
||||
performWriteOperation(Operation, OldArchive, NewMembers);
|
||||
return;
|
||||
case CreateSymTab:
|
||||
createSymbolTable(OldArchive);
|
||||
@ -949,7 +908,8 @@ static void performOperation(ArchiveOperation Operation,
|
||||
llvm_unreachable("Unknown operation.");
|
||||
}
|
||||
|
||||
static int performOperation(ArchiveOperation Operation) {
|
||||
static int performOperation(ArchiveOperation Operation,
|
||||
std::vector<NewArchiveIterator> *NewMembers) {
|
||||
// Create or open the archive object.
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>> Buf =
|
||||
MemoryBuffer::getFile(ArchiveName, -1, false);
|
||||
@ -968,7 +928,7 @@ static int performOperation(ArchiveOperation Operation) {
|
||||
<< "': " << EC.message() << "!\n";
|
||||
return 1;
|
||||
}
|
||||
performOperation(Operation, &Archive);
|
||||
performOperation(Operation, &Archive, NewMembers);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -983,22 +943,70 @@ static int performOperation(ArchiveOperation Operation) {
|
||||
}
|
||||
}
|
||||
|
||||
performOperation(Operation, nullptr);
|
||||
performOperation(Operation, nullptr, NewMembers);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void runMRIScript() {
|
||||
enum class MRICommand { AddMod, Create, Save, End, Invalid };
|
||||
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>> Buf = MemoryBuffer::getSTDIN();
|
||||
failIfError(Buf.getError());
|
||||
const MemoryBuffer &Ref = *Buf.get();
|
||||
bool Saved = false;
|
||||
std::vector<NewArchiveIterator> NewMembers;
|
||||
|
||||
for (line_iterator I(Ref, /*SkipBlanks*/ true, ';'), E; I != E; ++I) {
|
||||
StringRef Line = *I;
|
||||
StringRef CommandStr, Rest;
|
||||
std::tie(CommandStr, Rest) = Line.split(' ');
|
||||
auto Command = StringSwitch<MRICommand>(CommandStr.lower())
|
||||
.Case("addmod", MRICommand::AddMod)
|
||||
.Case("create", MRICommand::Create)
|
||||
.Case("save", MRICommand::Save)
|
||||
.Case("end", MRICommand::End)
|
||||
.Default(MRICommand::Invalid);
|
||||
|
||||
switch (Command) {
|
||||
case MRICommand::AddMod:
|
||||
addMember(NewMembers, Rest, sys::path::filename(Rest));
|
||||
break;
|
||||
case MRICommand::Create:
|
||||
Create = true;
|
||||
if (!ArchiveName.empty())
|
||||
fail("Editing multiple archives not supported");
|
||||
if (Saved)
|
||||
fail("File already saved");
|
||||
ArchiveName = Rest;
|
||||
break;
|
||||
case MRICommand::Save:
|
||||
Saved = true;
|
||||
break;
|
||||
case MRICommand::End:
|
||||
break;
|
||||
case MRICommand::Invalid:
|
||||
fail("Unknown command: " + CommandStr);
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing to do if not saved.
|
||||
if (Saved)
|
||||
performOperation(ReplaceOrInsert, &NewMembers);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int ar_main(char **argv) {
|
||||
// Do our own parsing of the command line because the CommandLine utility
|
||||
// can't handle the grouped positional parameters without a dash.
|
||||
ArchiveOperation Operation = parseCommandLine();
|
||||
return performOperation(Operation);
|
||||
return performOperation(Operation, nullptr);
|
||||
}
|
||||
|
||||
int ranlib_main() {
|
||||
if (RestOfArgs.size() != 1)
|
||||
fail(ToolName + "takes just one archive as argument");
|
||||
ArchiveName = RestOfArgs[0];
|
||||
return performOperation(CreateSymTab);
|
||||
return performOperation(CreateSymTab, nullptr);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
Loading…
Reference in New Issue
Block a user