@@ -623,6 +623,54 @@ handleUserSection(const NewSectionInfo &NewSection,
623
623
return F (NewSection.SectionName , Data);
624
624
}
625
625
626
+ static Error verifyNoteSection (StringRef Name, endianness Endianness,
627
+ ArrayRef<uint8_t > Data) {
628
+ // An ELF note has the following structure:
629
+ // Name Size: 4 bytes (integer)
630
+ // Desc Size: 4 bytes (integer)
631
+ // Type : 4 bytes
632
+ // Name : variable size, padded to a 4 byte boundary
633
+ // Desc : variable size, padded to a 4 byte boundary
634
+
635
+ if (Data.empty ())
636
+ return Error::success ();
637
+
638
+ if (Data.size () < 12 ) {
639
+ std::string msg;
640
+ raw_string_ostream (msg)
641
+ << Name << " data must be either empty or at least 12 bytes long" ;
642
+ return createStringError (errc::invalid_argument, msg);
643
+ }
644
+ if (Data.size () % 4 != 0 ) {
645
+ std::string msg;
646
+ raw_string_ostream (msg)
647
+ << Name << " data size must be a multiple of 4 bytes" ;
648
+ return createStringError (errc::invalid_argument, msg);
649
+ }
650
+ ArrayRef<uint8_t > NameSize = Data.slice (0 , 4 );
651
+ ArrayRef<uint8_t > DescSize = Data.slice (4 , 4 );
652
+
653
+ uint32_t NameSizeValue = support::endian::read32 (NameSize.data (), Endianness);
654
+ uint32_t DescSizeValue = support::endian::read32 (DescSize.data (), Endianness);
655
+
656
+ uint64_t ExpectedDataSize =
657
+ /* NameSize=*/ 4 + /* DescSize=*/ 4 + /* Type=*/ 4 +
658
+ /* Name=*/ alignTo (NameSizeValue, 4 ) +
659
+ /* Desc=*/ alignTo (DescSizeValue, 4 );
660
+ uint64_t ActualDataSize = Data.size ();
661
+ if (ActualDataSize != ExpectedDataSize) {
662
+ std::string msg;
663
+ raw_string_ostream (msg)
664
+ << Name
665
+ << " data size is incompatible with the content of "
666
+ " the name and description size fields:"
667
+ << " expecting " << ExpectedDataSize << " , found " << ActualDataSize;
668
+ return createStringError (errc::invalid_argument, msg);
669
+ }
670
+
671
+ return Error::success ();
672
+ }
673
+
626
674
// This function handles the high level operations of GNU objcopy including
627
675
// handling command line options. It's important to outline certain properties
628
676
// we expect to hold of the command line operations. Any operation that "keeps"
@@ -631,7 +679,7 @@ handleUserSection(const NewSectionInfo &NewSection,
631
679
// depend a) on the order the options occur in or b) on some opaque priority
632
680
// system. The only priority is that keeps/copies overrule removes.
633
681
static Error handleArgs (const CommonConfig &Config, const ELFConfig &ELFConfig,
634
- Object &Obj) {
682
+ ElfType OutputElfType, Object &Obj) {
635
683
if (Config.OutputArch ) {
636
684
Obj.Machine = Config.OutputArch ->EMachine ;
637
685
Obj.OSABI = Config.OutputArch ->OSABI ;
@@ -702,12 +750,19 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
702
750
if (Sec.Flags & SHF_ALLOC && Sec.Type != SHT_NOTE)
703
751
Sec.Type = SHT_NOBITS;
704
752
753
+ endianness E = OutputElfType == ELFT_ELF32LE || OutputElfType == ELFT_ELF64LE
754
+ ? endianness::little
755
+ : endianness::big;
756
+
705
757
for (const NewSectionInfo &AddedSection : Config.AddSection ) {
706
- auto AddSection = [&](StringRef Name, ArrayRef<uint8_t > Data) {
758
+ auto AddSection = [&](StringRef Name, ArrayRef<uint8_t > Data) -> Error {
707
759
OwnedDataSection &NewSection =
708
760
Obj.addSection <OwnedDataSection>(Name, Data);
709
- if (Name.starts_with (" .note" ) && Name != " .note.GNU-stack" )
761
+ if (Name.starts_with (" .note" ) && Name != " .note.GNU-stack" ) {
710
762
NewSection.Type = SHT_NOTE;
763
+ if (ELFConfig.VerifyNoteSections )
764
+ return verifyNoteSection (Name, E, Data);
765
+ }
711
766
return Error::success ();
712
767
};
713
768
if (Error E = handleUserSection (AddedSection, AddSection))
@@ -840,7 +895,7 @@ Error objcopy::elf::executeObjcopyOnIHex(const CommonConfig &Config,
840
895
841
896
const ElfType OutputElfType =
842
897
getOutputElfType (Config.OutputArch .value_or (MachineInfo ()));
843
- if (Error E = handleArgs (Config, ELFConfig, **Obj))
898
+ if (Error E = handleArgs (Config, ELFConfig, OutputElfType, **Obj))
844
899
return E;
845
900
return writeOutput (Config, **Obj, Out, OutputElfType);
846
901
}
@@ -858,7 +913,7 @@ Error objcopy::elf::executeObjcopyOnRawBinary(const CommonConfig &Config,
858
913
// (-B<arch>).
859
914
const ElfType OutputElfType =
860
915
getOutputElfType (Config.OutputArch .value_or (MachineInfo ()));
861
- if (Error E = handleArgs (Config, ELFConfig, **Obj))
916
+ if (Error E = handleArgs (Config, ELFConfig, OutputElfType, **Obj))
862
917
return E;
863
918
return writeOutput (Config, **Obj, Out, OutputElfType);
864
919
}
@@ -877,7 +932,7 @@ Error objcopy::elf::executeObjcopyOnBinary(const CommonConfig &Config,
877
932
? getOutputElfType (*Config.OutputArch )
878
933
: getOutputElfType (In);
879
934
880
- if (Error E = handleArgs (Config, ELFConfig, **Obj))
935
+ if (Error E = handleArgs (Config, ELFConfig, OutputElfType, **Obj))
881
936
return createFileError (Config.InputFilename , std::move (E));
882
937
883
938
if (Error E = writeOutput (Config, **Obj, Out, OutputElfType))
0 commit comments