You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1418 lines
34 KiB

  1. // Copyright 2018 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // Package elf implements access to ELF object files.
  15. package elf
  16. import (
  17. "bytes"
  18. "compress/zlib"
  19. "encoding/binary"
  20. "errors"
  21. "fmt"
  22. "io"
  23. "os"
  24. "strings"
  25. "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/dwarf"
  26. )
  27. // seekStart, seekCurrent, seekEnd are copies of
  28. // io.SeekStart, io.SeekCurrent, and io.SeekEnd.
  29. // We can't use the ones from package io because
  30. // we want this code to build with Go 1.4 during
  31. // cmd/dist bootstrap.
  32. const (
  33. seekStart int = 0
  34. seekCurrent int = 1
  35. seekEnd int = 2
  36. )
  37. // TODO: error reporting detail
  38. /*
  39. * Internal ELF representation
  40. */
  41. // A FileHeader represents an ELF file header.
  42. type FileHeader struct {
  43. Class Class
  44. Data Data
  45. Version Version
  46. OSABI OSABI
  47. ABIVersion uint8
  48. ByteOrder binary.ByteOrder
  49. Type Type
  50. Machine Machine
  51. Entry uint64
  52. }
  53. // A File represents an open ELF file.
  54. type File struct {
  55. FileHeader
  56. Sections []*Section
  57. Progs []*Prog
  58. closer io.Closer
  59. gnuNeed []verneed
  60. gnuVersym []byte
  61. }
  62. // A SectionHeader represents a single ELF section header.
  63. type SectionHeader struct {
  64. Name string
  65. Type SectionType
  66. Flags SectionFlag
  67. Addr uint64
  68. Offset uint64
  69. Size uint64
  70. Link uint32
  71. Info uint32
  72. Addralign uint64
  73. Entsize uint64
  74. // FileSize is the size of this section in the file in bytes.
  75. // If a section is compressed, FileSize is the size of the
  76. // compressed data, while Size (above) is the size of the
  77. // uncompressed data.
  78. FileSize uint64
  79. }
  80. // A Section represents a single section in an ELF file.
  81. type Section struct {
  82. SectionHeader
  83. // Embed ReaderAt for ReadAt method.
  84. // Do not embed SectionReader directly
  85. // to avoid having Read and Seek.
  86. // If a client wants Read and Seek it must use
  87. // Open() to avoid fighting over the seek offset
  88. // with other clients.
  89. //
  90. // ReaderAt may be nil if the section is not easily available
  91. // in a random-access form. For example, a compressed section
  92. // may have a nil ReaderAt.
  93. io.ReaderAt
  94. sr *io.SectionReader
  95. compressionType CompressionType
  96. compressionOffset int64
  97. }
  98. // Data reads and returns the contents of the ELF section.
  99. // Even if the section is stored compressed in the ELF file,
  100. // Data returns uncompressed data.
  101. func (s *Section) Data() ([]byte, error) {
  102. dat := make([]byte, s.Size)
  103. n, err := io.ReadFull(s.Open(), dat)
  104. return dat[0:n], err
  105. }
  106. // stringTable reads and returns the string table given by the
  107. // specified link value.
  108. func (f *File) stringTable(link uint32) ([]byte, error) {
  109. if link <= 0 || link >= uint32(len(f.Sections)) {
  110. return nil, errors.New("section has invalid string table link")
  111. }
  112. return f.Sections[link].Data()
  113. }
  114. // Open returns a new ReadSeeker reading the ELF section.
  115. // Even if the section is stored compressed in the ELF file,
  116. // the ReadSeeker reads uncompressed data.
  117. func (s *Section) Open() io.ReadSeeker {
  118. if s.Flags&SHF_COMPRESSED == 0 {
  119. return io.NewSectionReader(s.sr, 0, 1<<63-1)
  120. }
  121. if s.compressionType == COMPRESS_ZLIB {
  122. return &readSeekerFromReader{
  123. reset: func() (io.Reader, error) {
  124. fr := io.NewSectionReader(s.sr, s.compressionOffset, int64(s.FileSize)-s.compressionOffset)
  125. return zlib.NewReader(fr)
  126. },
  127. size: int64(s.Size),
  128. }
  129. }
  130. err := &FormatError{int64(s.Offset), "unknown compression type", s.compressionType}
  131. return errorReader{err}
  132. }
  133. // A ProgHeader represents a single ELF program header.
  134. type ProgHeader struct {
  135. Type ProgType
  136. Flags ProgFlag
  137. Off uint64
  138. Vaddr uint64
  139. Paddr uint64
  140. Filesz uint64
  141. Memsz uint64
  142. Align uint64
  143. }
  144. // A Prog represents a single ELF program header in an ELF binary.
  145. type Prog struct {
  146. ProgHeader
  147. // Embed ReaderAt for ReadAt method.
  148. // Do not embed SectionReader directly
  149. // to avoid having Read and Seek.
  150. // If a client wants Read and Seek it must use
  151. // Open() to avoid fighting over the seek offset
  152. // with other clients.
  153. io.ReaderAt
  154. sr *io.SectionReader
  155. }
  156. // Open returns a new ReadSeeker reading the ELF program body.
  157. func (p *Prog) Open() io.ReadSeeker { return io.NewSectionReader(p.sr, 0, 1<<63-1) }
  158. // A Symbol represents an entry in an ELF symbol table section.
  159. type Symbol struct {
  160. Name string
  161. Info, Other byte
  162. Section SectionIndex
  163. Value, Size uint64
  164. }
  165. /*
  166. * ELF reader
  167. */
  168. type FormatError struct {
  169. off int64
  170. msg string
  171. val interface{}
  172. }
  173. func (e *FormatError) Error() string {
  174. msg := e.msg
  175. if e.val != nil {
  176. msg += fmt.Sprintf(" '%v' ", e.val)
  177. }
  178. msg += fmt.Sprintf("in record at byte %#x", e.off)
  179. return msg
  180. }
  181. // Open opens the named file using os.Open and prepares it for use as an ELF binary.
  182. func Open(name string) (*File, error) {
  183. f, err := os.Open(name)
  184. if err != nil {
  185. return nil, err
  186. }
  187. ff, err := NewFile(f)
  188. if err != nil {
  189. f.Close()
  190. return nil, err
  191. }
  192. ff.closer = f
  193. return ff, nil
  194. }
  195. // Close closes the File.
  196. // If the File was created using NewFile directly instead of Open,
  197. // Close has no effect.
  198. func (f *File) Close() error {
  199. var err error
  200. if f.closer != nil {
  201. err = f.closer.Close()
  202. f.closer = nil
  203. }
  204. return err
  205. }
  206. // SectionByType returns the first section in f with the
  207. // given type, or nil if there is no such section.
  208. func (f *File) SectionByType(typ SectionType) *Section {
  209. for _, s := range f.Sections {
  210. if s.Type == typ {
  211. return s
  212. }
  213. }
  214. return nil
  215. }
  216. // NewFile creates a new File for accessing an ELF binary in an underlying reader.
  217. // The ELF binary is expected to start at position 0 in the ReaderAt.
  218. func NewFile(r io.ReaderAt) (*File, error) {
  219. sr := io.NewSectionReader(r, 0, 1<<63-1)
  220. // Read and decode ELF identifier
  221. var ident [16]uint8
  222. if _, err := r.ReadAt(ident[0:], 0); err != nil {
  223. return nil, err
  224. }
  225. if ident[0] != '\x7f' || ident[1] != 'E' || ident[2] != 'L' || ident[3] != 'F' {
  226. return nil, &FormatError{0, "bad magic number", ident[0:4]}
  227. }
  228. f := new(File)
  229. f.Class = Class(ident[EI_CLASS])
  230. switch f.Class {
  231. case ELFCLASS32:
  232. case ELFCLASS64:
  233. // ok
  234. default:
  235. return nil, &FormatError{0, "unknown ELF class", f.Class}
  236. }
  237. f.Data = Data(ident[EI_DATA])
  238. switch f.Data {
  239. case ELFDATA2LSB:
  240. f.ByteOrder = binary.LittleEndian
  241. case ELFDATA2MSB:
  242. f.ByteOrder = binary.BigEndian
  243. default:
  244. return nil, &FormatError{0, "unknown ELF data encoding", f.Data}
  245. }
  246. f.Version = Version(ident[EI_VERSION])
  247. if f.Version != EV_CURRENT {
  248. return nil, &FormatError{0, "unknown ELF version", f.Version}
  249. }
  250. f.OSABI = OSABI(ident[EI_OSABI])
  251. f.ABIVersion = ident[EI_ABIVERSION]
  252. // Read ELF file header
  253. var phoff int64
  254. var phentsize, phnum int
  255. var shoff int64
  256. var shentsize, shnum, shstrndx int
  257. shstrndx = -1
  258. switch f.Class {
  259. case ELFCLASS32:
  260. hdr := new(Header32)
  261. sr.Seek(0, seekStart)
  262. if err := binary.Read(sr, f.ByteOrder, hdr); err != nil {
  263. return nil, err
  264. }
  265. f.Type = Type(hdr.Type)
  266. f.Machine = Machine(hdr.Machine)
  267. f.Entry = uint64(hdr.Entry)
  268. if v := Version(hdr.Version); v != f.Version {
  269. return nil, &FormatError{0, "mismatched ELF version", v}
  270. }
  271. phoff = int64(hdr.Phoff)
  272. phentsize = int(hdr.Phentsize)
  273. phnum = int(hdr.Phnum)
  274. shoff = int64(hdr.Shoff)
  275. shentsize = int(hdr.Shentsize)
  276. shnum = int(hdr.Shnum)
  277. shstrndx = int(hdr.Shstrndx)
  278. case ELFCLASS64:
  279. hdr := new(Header64)
  280. sr.Seek(0, seekStart)
  281. if err := binary.Read(sr, f.ByteOrder, hdr); err != nil {
  282. return nil, err
  283. }
  284. f.Type = Type(hdr.Type)
  285. f.Machine = Machine(hdr.Machine)
  286. f.Entry = hdr.Entry
  287. if v := Version(hdr.Version); v != f.Version {
  288. return nil, &FormatError{0, "mismatched ELF version", v}
  289. }
  290. phoff = int64(hdr.Phoff)
  291. phentsize = int(hdr.Phentsize)
  292. phnum = int(hdr.Phnum)
  293. shoff = int64(hdr.Shoff)
  294. shentsize = int(hdr.Shentsize)
  295. shnum = int(hdr.Shnum)
  296. shstrndx = int(hdr.Shstrndx)
  297. }
  298. if shnum > 0 && shoff > 0 && (shstrndx < 0 || shstrndx >= shnum) {
  299. return nil, &FormatError{0, "invalid ELF shstrndx", shstrndx}
  300. }
  301. // Read program headers
  302. f.Progs = make([]*Prog, phnum)
  303. for i := 0; i < phnum; i++ {
  304. off := phoff + int64(i)*int64(phentsize)
  305. sr.Seek(off, seekStart)
  306. p := new(Prog)
  307. switch f.Class {
  308. case ELFCLASS32:
  309. ph := new(Prog32)
  310. if err := binary.Read(sr, f.ByteOrder, ph); err != nil {
  311. return nil, err
  312. }
  313. p.ProgHeader = ProgHeader{
  314. Type: ProgType(ph.Type),
  315. Flags: ProgFlag(ph.Flags),
  316. Off: uint64(ph.Off),
  317. Vaddr: uint64(ph.Vaddr),
  318. Paddr: uint64(ph.Paddr),
  319. Filesz: uint64(ph.Filesz),
  320. Memsz: uint64(ph.Memsz),
  321. Align: uint64(ph.Align),
  322. }
  323. case ELFCLASS64:
  324. ph := new(Prog64)
  325. if err := binary.Read(sr, f.ByteOrder, ph); err != nil {
  326. return nil, err
  327. }
  328. p.ProgHeader = ProgHeader{
  329. Type: ProgType(ph.Type),
  330. Flags: ProgFlag(ph.Flags),
  331. Off: ph.Off,
  332. Vaddr: ph.Vaddr,
  333. Paddr: ph.Paddr,
  334. Filesz: ph.Filesz,
  335. Memsz: ph.Memsz,
  336. Align: ph.Align,
  337. }
  338. }
  339. p.sr = io.NewSectionReader(r, int64(p.Off), int64(p.Filesz))
  340. p.ReaderAt = p.sr
  341. f.Progs[i] = p
  342. }
  343. // Read section headers
  344. f.Sections = make([]*Section, shnum)
  345. names := make([]uint32, shnum)
  346. for i := 0; i < shnum; i++ {
  347. off := shoff + int64(i)*int64(shentsize)
  348. sr.Seek(off, seekStart)
  349. s := new(Section)
  350. switch f.Class {
  351. case ELFCLASS32:
  352. sh := new(Section32)
  353. if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
  354. return nil, err
  355. }
  356. names[i] = sh.Name
  357. s.SectionHeader = SectionHeader{
  358. Type: SectionType(sh.Type),
  359. Flags: SectionFlag(sh.Flags),
  360. Addr: uint64(sh.Addr),
  361. Offset: uint64(sh.Off),
  362. FileSize: uint64(sh.Size),
  363. Link: sh.Link,
  364. Info: sh.Info,
  365. Addralign: uint64(sh.Addralign),
  366. Entsize: uint64(sh.Entsize),
  367. }
  368. case ELFCLASS64:
  369. sh := new(Section64)
  370. if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
  371. return nil, err
  372. }
  373. names[i] = sh.Name
  374. s.SectionHeader = SectionHeader{
  375. Type: SectionType(sh.Type),
  376. Flags: SectionFlag(sh.Flags),
  377. Offset: sh.Off,
  378. FileSize: sh.Size,
  379. Addr: sh.Addr,
  380. Link: sh.Link,
  381. Info: sh.Info,
  382. Addralign: sh.Addralign,
  383. Entsize: sh.Entsize,
  384. }
  385. }
  386. s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.FileSize))
  387. if s.Flags&SHF_COMPRESSED == 0 {
  388. s.ReaderAt = s.sr
  389. s.Size = s.FileSize
  390. } else {
  391. // Read the compression header.
  392. switch f.Class {
  393. case ELFCLASS32:
  394. ch := new(Chdr32)
  395. if err := binary.Read(s.sr, f.ByteOrder, ch); err != nil {
  396. return nil, err
  397. }
  398. s.compressionType = CompressionType(ch.Type)
  399. s.Size = uint64(ch.Size)
  400. s.Addralign = uint64(ch.Addralign)
  401. s.compressionOffset = int64(binary.Size(ch))
  402. case ELFCLASS64:
  403. ch := new(Chdr64)
  404. if err := binary.Read(s.sr, f.ByteOrder, ch); err != nil {
  405. return nil, err
  406. }
  407. s.compressionType = CompressionType(ch.Type)
  408. s.Size = ch.Size
  409. s.Addralign = ch.Addralign
  410. s.compressionOffset = int64(binary.Size(ch))
  411. }
  412. }
  413. f.Sections[i] = s
  414. }
  415. if len(f.Sections) == 0 {
  416. return f, nil
  417. }
  418. // Load section header string table.
  419. shstrtab, err := f.Sections[shstrndx].Data()
  420. if err != nil {
  421. return nil, err
  422. }
  423. for i, s := range f.Sections {
  424. var ok bool
  425. s.Name, ok = getString(shstrtab, int(names[i]))
  426. if !ok {
  427. return nil, &FormatError{shoff + int64(i*shentsize), "bad section name index", names[i]}
  428. }
  429. }
  430. return f, nil
  431. }
  432. // getSymbols returns a slice of Symbols from parsing the symbol table
  433. // with the given type, along with the associated string table.
  434. func (f *File) getSymbols(typ SectionType) ([]Symbol, []byte, error) {
  435. switch f.Class {
  436. case ELFCLASS64:
  437. return f.getSymbols64(typ)
  438. case ELFCLASS32:
  439. return f.getSymbols32(typ)
  440. }
  441. return nil, nil, errors.New("not implemented")
  442. }
  443. // ErrNoSymbols is returned by File.Symbols and File.DynamicSymbols
  444. // if there is no such section in the File.
  445. var ErrNoSymbols = errors.New("no symbol section")
  446. func (f *File) getSymbols32(typ SectionType) ([]Symbol, []byte, error) {
  447. symtabSection := f.SectionByType(typ)
  448. if symtabSection == nil {
  449. return nil, nil, ErrNoSymbols
  450. }
  451. data, err := symtabSection.Data()
  452. if err != nil {
  453. return nil, nil, errors.New("cannot load symbol section")
  454. }
  455. symtab := bytes.NewReader(data)
  456. if symtab.Len()%Sym32Size != 0 {
  457. return nil, nil, errors.New("length of symbol section is not a multiple of SymSize")
  458. }
  459. strdata, err := f.stringTable(symtabSection.Link)
  460. if err != nil {
  461. return nil, nil, errors.New("cannot load string table section")
  462. }
  463. // The first entry is all zeros.
  464. var skip [Sym32Size]byte
  465. symtab.Read(skip[:])
  466. symbols := make([]Symbol, symtab.Len()/Sym32Size)
  467. i := 0
  468. var sym Sym32
  469. for symtab.Len() > 0 {
  470. binary.Read(symtab, f.ByteOrder, &sym)
  471. str, _ := getString(strdata, int(sym.Name))
  472. symbols[i].Name = str
  473. symbols[i].Info = sym.Info
  474. symbols[i].Other = sym.Other
  475. symbols[i].Section = SectionIndex(sym.Shndx)
  476. symbols[i].Value = uint64(sym.Value)
  477. symbols[i].Size = uint64(sym.Size)
  478. i++
  479. }
  480. return symbols, strdata, nil
  481. }
  482. func (f *File) getSymbols64(typ SectionType) ([]Symbol, []byte, error) {
  483. symtabSection := f.SectionByType(typ)
  484. if symtabSection == nil {
  485. return nil, nil, ErrNoSymbols
  486. }
  487. data, err := symtabSection.Data()
  488. if err != nil {
  489. return nil, nil, errors.New("cannot load symbol section")
  490. }
  491. symtab := bytes.NewReader(data)
  492. if symtab.Len()%Sym64Size != 0 {
  493. return nil, nil, errors.New("length of symbol section is not a multiple of Sym64Size")
  494. }
  495. strdata, err := f.stringTable(symtabSection.Link)
  496. if err != nil {
  497. return nil, nil, errors.New("cannot load string table section")
  498. }
  499. // The first entry is all zeros.
  500. var skip [Sym64Size]byte
  501. symtab.Read(skip[:])
  502. symbols := make([]Symbol, symtab.Len()/Sym64Size)
  503. i := 0
  504. var sym Sym64
  505. for symtab.Len() > 0 {
  506. binary.Read(symtab, f.ByteOrder, &sym)
  507. str, _ := getString(strdata, int(sym.Name))
  508. symbols[i].Name = str
  509. symbols[i].Info = sym.Info
  510. symbols[i].Other = sym.Other
  511. symbols[i].Section = SectionIndex(sym.Shndx)
  512. symbols[i].Value = sym.Value
  513. symbols[i].Size = sym.Size
  514. i++
  515. }
  516. return symbols, strdata, nil
  517. }
  518. // getString extracts a string from an ELF string table.
  519. func getString(section []byte, start int) (string, bool) {
  520. if start < 0 || start >= len(section) {
  521. return "", false
  522. }
  523. for end := start; end < len(section); end++ {
  524. if section[end] == 0 {
  525. return string(section[start:end]), true
  526. }
  527. }
  528. return "", false
  529. }
  530. // Section returns a section with the given name, or nil if no such
  531. // section exists.
  532. func (f *File) Section(name string) *Section {
  533. for _, s := range f.Sections {
  534. if s.Name == name {
  535. return s
  536. }
  537. }
  538. return nil
  539. }
  540. // applyRelocations applies relocations to dst. rels is a relocations section
  541. // in REL or RELA format.
  542. func (f *File) applyRelocations(dst []byte, rels []byte) error {
  543. switch {
  544. case f.Class == ELFCLASS64 && f.Machine == EM_X86_64:
  545. return f.applyRelocationsAMD64(dst, rels)
  546. case f.Class == ELFCLASS32 && f.Machine == EM_386:
  547. return f.applyRelocations386(dst, rels)
  548. case f.Class == ELFCLASS32 && f.Machine == EM_ARM:
  549. return f.applyRelocationsARM(dst, rels)
  550. case f.Class == ELFCLASS64 && f.Machine == EM_AARCH64:
  551. return f.applyRelocationsARM64(dst, rels)
  552. case f.Class == ELFCLASS32 && f.Machine == EM_PPC:
  553. return f.applyRelocationsPPC(dst, rels)
  554. case f.Class == ELFCLASS64 && f.Machine == EM_PPC64:
  555. return f.applyRelocationsPPC64(dst, rels)
  556. case f.Class == ELFCLASS32 && f.Machine == EM_MIPS:
  557. return f.applyRelocationsMIPS(dst, rels)
  558. case f.Class == ELFCLASS64 && f.Machine == EM_MIPS:
  559. return f.applyRelocationsMIPS64(dst, rels)
  560. case f.Class == ELFCLASS64 && f.Machine == EM_RISCV:
  561. return f.applyRelocationsRISCV64(dst, rels)
  562. case f.Class == ELFCLASS64 && f.Machine == EM_S390:
  563. return f.applyRelocationss390x(dst, rels)
  564. case f.Class == ELFCLASS64 && f.Machine == EM_SPARCV9:
  565. return f.applyRelocationsSPARC64(dst, rels)
  566. default:
  567. return errors.New("applyRelocations: not implemented")
  568. }
  569. }
  570. func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error {
  571. // 24 is the size of Rela64.
  572. if len(rels)%24 != 0 {
  573. return errors.New("length of relocation section is not a multiple of 24")
  574. }
  575. symbols, _, err := f.getSymbols(SHT_SYMTAB)
  576. if err != nil {
  577. return err
  578. }
  579. b := bytes.NewReader(rels)
  580. var rela Rela64
  581. for b.Len() > 0 {
  582. binary.Read(b, f.ByteOrder, &rela)
  583. symNo := rela.Info >> 32
  584. t := R_X86_64(rela.Info & 0xffff)
  585. if symNo == 0 || symNo > uint64(len(symbols)) {
  586. continue
  587. }
  588. sym := &symbols[symNo-1]
  589. if SymType(sym.Info&0xf) != STT_SECTION {
  590. // We don't handle non-section relocations for now.
  591. continue
  592. }
  593. // There are relocations, so this must be a normal
  594. // object file, and we only look at section symbols,
  595. // so we assume that the symbol value is 0.
  596. switch t {
  597. case R_X86_64_64:
  598. if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
  599. continue
  600. }
  601. f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend))
  602. case R_X86_64_32:
  603. if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
  604. continue
  605. }
  606. f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend))
  607. }
  608. }
  609. return nil
  610. }
  611. func (f *File) applyRelocations386(dst []byte, rels []byte) error {
  612. // 8 is the size of Rel32.
  613. if len(rels)%8 != 0 {
  614. return errors.New("length of relocation section is not a multiple of 8")
  615. }
  616. symbols, _, err := f.getSymbols(SHT_SYMTAB)
  617. if err != nil {
  618. return err
  619. }
  620. b := bytes.NewReader(rels)
  621. var rel Rel32
  622. for b.Len() > 0 {
  623. binary.Read(b, f.ByteOrder, &rel)
  624. symNo := rel.Info >> 8
  625. t := R_386(rel.Info & 0xff)
  626. if symNo == 0 || symNo > uint32(len(symbols)) {
  627. continue
  628. }
  629. sym := &symbols[symNo-1]
  630. if t == R_386_32 {
  631. if rel.Off+4 >= uint32(len(dst)) {
  632. continue
  633. }
  634. val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4])
  635. val += uint32(sym.Value)
  636. f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val)
  637. }
  638. }
  639. return nil
  640. }
  641. func (f *File) applyRelocationsARM(dst []byte, rels []byte) error {
  642. // 8 is the size of Rel32.
  643. if len(rels)%8 != 0 {
  644. return errors.New("length of relocation section is not a multiple of 8")
  645. }
  646. symbols, _, err := f.getSymbols(SHT_SYMTAB)
  647. if err != nil {
  648. return err
  649. }
  650. b := bytes.NewReader(rels)
  651. var rel Rel32
  652. for b.Len() > 0 {
  653. binary.Read(b, f.ByteOrder, &rel)
  654. symNo := rel.Info >> 8
  655. t := R_ARM(rel.Info & 0xff)
  656. if symNo == 0 || symNo > uint32(len(symbols)) {
  657. continue
  658. }
  659. sym := &symbols[symNo-1]
  660. switch t {
  661. case R_ARM_ABS32:
  662. if rel.Off+4 >= uint32(len(dst)) {
  663. continue
  664. }
  665. val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4])
  666. val += uint32(sym.Value)
  667. f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val)
  668. }
  669. }
  670. return nil
  671. }
  672. func (f *File) applyRelocationsARM64(dst []byte, rels []byte) error {
  673. // 24 is the size of Rela64.
  674. if len(rels)%24 != 0 {
  675. return errors.New("length of relocation section is not a multiple of 24")
  676. }
  677. symbols, _, err := f.getSymbols(SHT_SYMTAB)
  678. if err != nil {
  679. return err
  680. }
  681. b := bytes.NewReader(rels)
  682. var rela Rela64
  683. for b.Len() > 0 {
  684. binary.Read(b, f.ByteOrder, &rela)
  685. symNo := rela.Info >> 32
  686. t := R_AARCH64(rela.Info & 0xffff)
  687. if symNo == 0 || symNo > uint64(len(symbols)) {
  688. continue
  689. }
  690. sym := &symbols[symNo-1]
  691. if SymType(sym.Info&0xf) != STT_SECTION {
  692. // We don't handle non-section relocations for now.
  693. continue
  694. }
  695. // There are relocations, so this must be a normal
  696. // object file, and we only look at section symbols,
  697. // so we assume that the symbol value is 0.
  698. switch t {
  699. case R_AARCH64_ABS64:
  700. if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
  701. continue
  702. }
  703. f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend))
  704. case R_AARCH64_ABS32:
  705. if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
  706. continue
  707. }
  708. f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend))
  709. }
  710. }
  711. return nil
  712. }
  713. func (f *File) applyRelocationsPPC(dst []byte, rels []byte) error {
  714. // 12 is the size of Rela32.
  715. if len(rels)%12 != 0 {
  716. return errors.New("length of relocation section is not a multiple of 12")
  717. }
  718. symbols, _, err := f.getSymbols(SHT_SYMTAB)
  719. if err != nil {
  720. return err
  721. }
  722. b := bytes.NewReader(rels)
  723. var rela Rela32
  724. for b.Len() > 0 {
  725. binary.Read(b, f.ByteOrder, &rela)
  726. symNo := rela.Info >> 8
  727. t := R_PPC(rela.Info & 0xff)
  728. if symNo == 0 || symNo > uint32(len(symbols)) {
  729. continue
  730. }
  731. sym := &symbols[symNo-1]
  732. if SymType(sym.Info&0xf) != STT_SECTION {
  733. // We don't handle non-section relocations for now.
  734. continue
  735. }
  736. switch t {
  737. case R_PPC_ADDR32:
  738. if rela.Off+4 >= uint32(len(dst)) || rela.Addend < 0 {
  739. continue
  740. }
  741. f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend))
  742. }
  743. }
  744. return nil
  745. }
  746. func (f *File) applyRelocationsPPC64(dst []byte, rels []byte) error {
  747. // 24 is the size of Rela64.
  748. if len(rels)%24 != 0 {
  749. return errors.New("length of relocation section is not a multiple of 24")
  750. }
  751. symbols, _, err := f.getSymbols(SHT_SYMTAB)
  752. if err != nil {
  753. return err
  754. }
  755. b := bytes.NewReader(rels)
  756. var rela Rela64
  757. for b.Len() > 0 {
  758. binary.Read(b, f.ByteOrder, &rela)
  759. symNo := rela.Info >> 32
  760. t := R_PPC64(rela.Info & 0xffff)
  761. if symNo == 0 || symNo > uint64(len(symbols)) {
  762. continue
  763. }
  764. sym := &symbols[symNo-1]
  765. if SymType(sym.Info&0xf) != STT_SECTION {
  766. // We don't handle non-section relocations for now.
  767. continue
  768. }
  769. switch t {
  770. case R_PPC64_ADDR64:
  771. if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
  772. continue
  773. }
  774. f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend))
  775. case R_PPC64_ADDR32:
  776. if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
  777. continue
  778. }
  779. f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend))
  780. }
  781. }
  782. return nil
  783. }
  784. func (f *File) applyRelocationsMIPS(dst []byte, rels []byte) error {
  785. // 8 is the size of Rel32.
  786. if len(rels)%8 != 0 {
  787. return errors.New("length of relocation section is not a multiple of 8")
  788. }
  789. symbols, _, err := f.getSymbols(SHT_SYMTAB)
  790. if err != nil {
  791. return err
  792. }
  793. b := bytes.NewReader(rels)
  794. var rel Rel32
  795. for b.Len() > 0 {
  796. binary.Read(b, f.ByteOrder, &rel)
  797. symNo := rel.Info >> 8
  798. t := R_MIPS(rel.Info & 0xff)
  799. if symNo == 0 || symNo > uint32(len(symbols)) {
  800. continue
  801. }
  802. sym := &symbols[symNo-1]
  803. switch t {
  804. case R_MIPS_32:
  805. if rel.Off+4 >= uint32(len(dst)) {
  806. continue
  807. }
  808. val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4])
  809. val += uint32(sym.Value)
  810. f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val)
  811. }
  812. }
  813. return nil
  814. }
  815. func (f *File) applyRelocationsMIPS64(dst []byte, rels []byte) error {
  816. // 24 is the size of Rela64.
  817. if len(rels)%24 != 0 {
  818. return errors.New("length of relocation section is not a multiple of 24")
  819. }
  820. symbols, _, err := f.getSymbols(SHT_SYMTAB)
  821. if err != nil {
  822. return err
  823. }
  824. b := bytes.NewReader(rels)
  825. var rela Rela64
  826. for b.Len() > 0 {
  827. binary.Read(b, f.ByteOrder, &rela)
  828. var symNo uint64
  829. var t R_MIPS
  830. if f.ByteOrder == binary.BigEndian {
  831. symNo = rela.Info >> 32
  832. t = R_MIPS(rela.Info & 0xff)
  833. } else {
  834. symNo = rela.Info & 0xffffffff
  835. t = R_MIPS(rela.Info >> 56)
  836. }
  837. if symNo == 0 || symNo > uint64(len(symbols)) {
  838. continue
  839. }
  840. sym := &symbols[symNo-1]
  841. if SymType(sym.Info&0xf) != STT_SECTION {
  842. // We don't handle non-section relocations for now.
  843. continue
  844. }
  845. switch t {
  846. case R_MIPS_64:
  847. if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
  848. continue
  849. }
  850. f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend))
  851. case R_MIPS_32:
  852. if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
  853. continue
  854. }
  855. f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend))
  856. }
  857. }
  858. return nil
  859. }
  860. func (f *File) applyRelocationsRISCV64(dst []byte, rels []byte) error {
  861. // 24 is the size of Rela64.
  862. if len(rels)%24 != 0 {
  863. return errors.New("length of relocation section is not a multiple of 24")
  864. }
  865. symbols, _, err := f.getSymbols(SHT_SYMTAB)
  866. if err != nil {
  867. return err
  868. }
  869. b := bytes.NewReader(rels)
  870. var rela Rela64
  871. for b.Len() > 0 {
  872. binary.Read(b, f.ByteOrder, &rela)
  873. symNo := rela.Info >> 32
  874. t := R_RISCV(rela.Info & 0xffff)
  875. if symNo == 0 || symNo > uint64(len(symbols)) {
  876. continue
  877. }
  878. sym := &symbols[symNo-1]
  879. switch SymType(sym.Info & 0xf) {
  880. case STT_SECTION, STT_NOTYPE:
  881. break
  882. default:
  883. continue
  884. }
  885. switch t {
  886. case R_RISCV_64:
  887. if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
  888. continue
  889. }
  890. val := sym.Value + uint64(rela.Addend)
  891. f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val)
  892. case R_RISCV_32:
  893. if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
  894. continue
  895. }
  896. val := uint32(sym.Value) + uint32(rela.Addend)
  897. f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val)
  898. }
  899. }
  900. return nil
  901. }
  902. func (f *File) applyRelocationss390x(dst []byte, rels []byte) error {
  903. // 24 is the size of Rela64.
  904. if len(rels)%24 != 0 {
  905. return errors.New("length of relocation section is not a multiple of 24")
  906. }
  907. symbols, _, err := f.getSymbols(SHT_SYMTAB)
  908. if err != nil {
  909. return err
  910. }
  911. b := bytes.NewReader(rels)
  912. var rela Rela64
  913. for b.Len() > 0 {
  914. binary.Read(b, f.ByteOrder, &rela)
  915. symNo := rela.Info >> 32
  916. t := R_390(rela.Info & 0xffff)
  917. if symNo == 0 || symNo > uint64(len(symbols)) {
  918. continue
  919. }
  920. sym := &symbols[symNo-1]
  921. switch SymType(sym.Info & 0xf) {
  922. case STT_SECTION, STT_NOTYPE:
  923. break
  924. default:
  925. continue
  926. }
  927. switch t {
  928. case R_390_64:
  929. if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
  930. continue
  931. }
  932. val := sym.Value + uint64(rela.Addend)
  933. f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val)
  934. case R_390_32:
  935. if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
  936. continue
  937. }
  938. val := uint32(sym.Value) + uint32(rela.Addend)
  939. f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val)
  940. }
  941. }
  942. return nil
  943. }
  944. func (f *File) applyRelocationsSPARC64(dst []byte, rels []byte) error {
  945. // 24 is the size of Rela64.
  946. if len(rels)%24 != 0 {
  947. return errors.New("length of relocation section is not a multiple of 24")
  948. }
  949. symbols, _, err := f.getSymbols(SHT_SYMTAB)
  950. if err != nil {
  951. return err
  952. }
  953. b := bytes.NewReader(rels)
  954. var rela Rela64
  955. for b.Len() > 0 {
  956. binary.Read(b, f.ByteOrder, &rela)
  957. symNo := rela.Info >> 32
  958. t := R_SPARC(rela.Info & 0xff)
  959. if symNo == 0 || symNo > uint64(len(symbols)) {
  960. continue
  961. }
  962. sym := &symbols[symNo-1]
  963. if SymType(sym.Info&0xf) != STT_SECTION {
  964. // We don't handle non-section relocations for now.
  965. continue
  966. }
  967. switch t {
  968. case R_SPARC_64, R_SPARC_UA64:
  969. if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
  970. continue
  971. }
  972. f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend))
  973. case R_SPARC_32, R_SPARC_UA32:
  974. if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
  975. continue
  976. }
  977. f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend))
  978. }
  979. }
  980. return nil
  981. }
  982. func (f *File) DWARF() (*dwarf.Data, error) {
  983. dwarfSuffix := func(s *Section) string {
  984. switch {
  985. case strings.HasPrefix(s.Name, ".debug_"):
  986. return s.Name[7:]
  987. case strings.HasPrefix(s.Name, ".zdebug_"):
  988. return s.Name[8:]
  989. default:
  990. return ""
  991. }
  992. }
  993. // sectionData gets the data for s, checks its size, and
  994. // applies any applicable relations.
  995. sectionData := func(i int, s *Section) ([]byte, error) {
  996. b, err := s.Data()
  997. if err != nil && uint64(len(b)) < s.Size {
  998. return nil, err
  999. }
  1000. if len(b) >= 12 && string(b[:4]) == "ZLIB" {
  1001. dlen := binary.BigEndian.Uint64(b[4:12])
  1002. dbuf := make([]byte, dlen)
  1003. r, err := zlib.NewReader(bytes.NewBuffer(b[12:]))
  1004. if err != nil {
  1005. return nil, err
  1006. }
  1007. if _, err := io.ReadFull(r, dbuf); err != nil {
  1008. return nil, err
  1009. }
  1010. if err := r.Close(); err != nil {
  1011. return nil, err
  1012. }
  1013. b = dbuf
  1014. }
  1015. for _, r := range f.Sections {
  1016. if r.Type != SHT_RELA && r.Type != SHT_REL {
  1017. continue
  1018. }
  1019. if int(r.Info) != i {
  1020. continue
  1021. }
  1022. rd, err := r.Data()
  1023. if err != nil {
  1024. return nil, err
  1025. }
  1026. err = f.applyRelocations(b, rd)
  1027. if err != nil {
  1028. return nil, err
  1029. }
  1030. }
  1031. return b, nil
  1032. }
  1033. // There are many other DWARF sections, but these
  1034. // are the ones the debug/dwarf package uses.
  1035. // Don't bother loading others.
  1036. var dat = map[string][]byte{"abbrev": nil, "info": nil, "str": nil, "line": nil, "ranges": nil}
  1037. for i, s := range f.Sections {
  1038. suffix := dwarfSuffix(s)
  1039. if suffix == "" {
  1040. continue
  1041. }
  1042. if _, ok := dat[suffix]; !ok {
  1043. continue
  1044. }
  1045. b, err := sectionData(i, s)
  1046. if err != nil {
  1047. return nil, err
  1048. }
  1049. dat[suffix] = b
  1050. }
  1051. d, err := dwarf.New(dat["abbrev"], nil, nil, dat["info"], dat["line"], nil, dat["ranges"], dat["str"])
  1052. if err != nil {
  1053. return nil, err
  1054. }
  1055. // Look for DWARF4 .debug_types sections.
  1056. for i, s := range f.Sections {
  1057. suffix := dwarfSuffix(s)
  1058. if suffix != "types" {
  1059. continue
  1060. }
  1061. b, err := sectionData(i, s)
  1062. if err != nil {
  1063. return nil, err
  1064. }
  1065. err = d.AddTypes(fmt.Sprintf("types-%d", i), b)
  1066. if err != nil {
  1067. return nil, err
  1068. }
  1069. }
  1070. return d, nil
  1071. }
  1072. // Symbols returns the symbol table for f. The symbols will be listed in the order
  1073. // they appear in f.
  1074. //
  1075. // For compatibility with Go 1.0, Symbols omits the null symbol at index 0.
  1076. // After retrieving the symbols as symtab, an externally supplied index x
  1077. // corresponds to symtab[x-1], not symtab[x].
  1078. func (f *File) Symbols() ([]Symbol, error) {
  1079. sym, _, err := f.getSymbols(SHT_SYMTAB)
  1080. return sym, err
  1081. }
  1082. // DynamicSymbols returns the dynamic symbol table for f. The symbols
  1083. // will be listed in the order they appear in f.
  1084. //
  1085. // For compatibility with Symbols, DynamicSymbols omits the null symbol at index 0.
  1086. // After retrieving the symbols as symtab, an externally supplied index x
  1087. // corresponds to symtab[x-1], not symtab[x].
  1088. func (f *File) DynamicSymbols() ([]Symbol, error) {
  1089. sym, _, err := f.getSymbols(SHT_DYNSYM)
  1090. return sym, err
  1091. }
  1092. type ImportedSymbol struct {
  1093. Name string
  1094. Version string
  1095. Library string
  1096. }
  1097. // ImportedSymbols returns the names of all symbols
  1098. // referred to by the binary f that are expected to be
  1099. // satisfied by other libraries at dynamic load time.
  1100. // It does not return weak symbols.
  1101. func (f *File) ImportedSymbols() ([]ImportedSymbol, error) {
  1102. sym, str, err := f.getSymbols(SHT_DYNSYM)
  1103. if err != nil {
  1104. return nil, err
  1105. }
  1106. f.gnuVersionInit(str)
  1107. var all []ImportedSymbol
  1108. for i, s := range sym {
  1109. if ST_BIND(s.Info) == STB_GLOBAL && s.Section == SHN_UNDEF {
  1110. all = append(all, ImportedSymbol{Name: s.Name})
  1111. f.gnuVersion(i, &all[len(all)-1])
  1112. }
  1113. }
  1114. return all, nil
  1115. }
  1116. type verneed struct {
  1117. File string
  1118. Name string
  1119. }
  1120. // gnuVersionInit parses the GNU version tables
  1121. // for use by calls to gnuVersion.
  1122. func (f *File) gnuVersionInit(str []byte) {
  1123. // Accumulate verneed information.
  1124. vn := f.SectionByType(SHT_GNU_VERNEED)
  1125. if vn == nil {
  1126. return
  1127. }
  1128. d, _ := vn.Data()
  1129. var need []verneed
  1130. i := 0
  1131. for {
  1132. if i+16 > len(d) {
  1133. break
  1134. }
  1135. vers := f.ByteOrder.Uint16(d[i : i+2])
  1136. if vers != 1 {
  1137. break
  1138. }
  1139. cnt := f.ByteOrder.Uint16(d[i+2 : i+4])
  1140. fileoff := f.ByteOrder.Uint32(d[i+4 : i+8])
  1141. aux := f.ByteOrder.Uint32(d[i+8 : i+12])
  1142. next := f.ByteOrder.Uint32(d[i+12 : i+16])
  1143. file, _ := getString(str, int(fileoff))
  1144. var name string
  1145. j := i + int(aux)
  1146. for c := 0; c < int(cnt); c++ {
  1147. if j+16 > len(d) {
  1148. break
  1149. }
  1150. // hash := f.ByteOrder.Uint32(d[j:j+4])
  1151. // flags := f.ByteOrder.Uint16(d[j+4:j+6])
  1152. other := f.ByteOrder.Uint16(d[j+6 : j+8])
  1153. nameoff := f.ByteOrder.Uint32(d[j+8 : j+12])
  1154. next := f.ByteOrder.Uint32(d[j+12 : j+16])
  1155. name, _ = getString(str, int(nameoff))
  1156. ndx := int(other)
  1157. if ndx >= len(need) {
  1158. a := make([]verneed, 2*(ndx+1))
  1159. copy(a, need)
  1160. need = a
  1161. }
  1162. need[ndx] = verneed{file, name}
  1163. if next == 0 {
  1164. break
  1165. }
  1166. j += int(next)
  1167. }
  1168. if next == 0 {
  1169. break
  1170. }
  1171. i += int(next)
  1172. }
  1173. // Versym parallels symbol table, indexing into verneed.
  1174. vs := f.SectionByType(SHT_GNU_VERSYM)
  1175. if vs == nil {
  1176. return
  1177. }
  1178. d, _ = vs.Data()
  1179. f.gnuNeed = need
  1180. f.gnuVersym = d
  1181. }
  1182. // gnuVersion adds Library and Version information to sym,
  1183. // which came from offset i of the symbol table.
  1184. func (f *File) gnuVersion(i int, sym *ImportedSymbol) {
  1185. // Each entry is two bytes.
  1186. i = (i + 1) * 2
  1187. if i >= len(f.gnuVersym) {
  1188. return
  1189. }
  1190. j := int(f.ByteOrder.Uint16(f.gnuVersym[i:]))
  1191. if j < 2 || j >= len(f.gnuNeed) {
  1192. return
  1193. }
  1194. n := &f.gnuNeed[j]
  1195. sym.Library = n.File
  1196. sym.Version = n.Name
  1197. }
  1198. // ImportedLibraries returns the names of all libraries
  1199. // referred to by the binary f that are expected to be
  1200. // linked with the binary at dynamic link time.
  1201. func (f *File) ImportedLibraries() ([]string, error) {
  1202. return f.DynString(DT_NEEDED)
  1203. }
  1204. // DynString returns the strings listed for the given tag in the file's dynamic
  1205. // section.
  1206. //
  1207. // The tag must be one that takes string values: DT_NEEDED, DT_SONAME, DT_RPATH, or
  1208. // DT_RUNPATH.
  1209. func (f *File) DynString(tag DynTag) ([]string, error) {
  1210. switch tag {
  1211. case DT_NEEDED, DT_SONAME, DT_RPATH, DT_RUNPATH:
  1212. default:
  1213. return nil, fmt.Errorf("non-string-valued tag %v", tag)
  1214. }
  1215. ds := f.SectionByType(SHT_DYNAMIC)
  1216. if ds == nil {
  1217. // not dynamic, so no libraries
  1218. return nil, nil
  1219. }
  1220. d, err := ds.Data()
  1221. if err != nil {
  1222. return nil, err
  1223. }
  1224. str, err := f.stringTable(ds.Link)
  1225. if err != nil {
  1226. return nil, err
  1227. }
  1228. var all []string
  1229. for len(d) > 0 {
  1230. var t DynTag
  1231. var v uint64
  1232. switch f.Class {
  1233. case ELFCLASS32:
  1234. t = DynTag(f.ByteOrder.Uint32(d[0:4]))
  1235. v = uint64(f.ByteOrder.Uint32(d[4:8]))
  1236. d = d[8:]
  1237. case ELFCLASS64:
  1238. t = DynTag(f.ByteOrder.Uint64(d[0:8]))
  1239. v = f.ByteOrder.Uint64(d[8:16])
  1240. d = d[16:]
  1241. }
  1242. if t == tag {
  1243. s, ok := getString(str, int(v))
  1244. if ok {
  1245. all = append(all, s)
  1246. }
  1247. }
  1248. }
  1249. return all, nil
  1250. }