Spracherkennung für: .go vermutete Sprache: Abap {ABAP[56] Delphi[54] SPS[54]} [Methode: maximale Elemente, drei Dimensionen]
// Copyright
2018 Google Inc. All rights reserved.
//
// Licensed
under the Apache License, Version
2.
0 (the
"License");
// you may not use this
file except
in compliance with the License.
// You may obtain a
copy of the License
at
//
//
http://www.apache.org/licenses/LICENSE-2.
0
//
// Unless required
by applicable law
or agreed
to in writing, software
// distributed
under the License
is distributed
on an
"AS IS" BASIS,
// WITHOUT WARRANTIES
OR CONDITIONS
OF ANY KIND, either express
or implied.
// See the License
for the specific
language governing permissions
and
// limitations
under the License.
package symbol_inject
import (
"debug/elf"
"fmt"
"io"
)
type mockableElfFile
interface {
Symbols() ([]elf.
Symbol, error)
Sections() []elf.SectionHeader
Type() elf.
Type
}
var _ mockableElfFile = elfFileWrapper{}
type elfFileWrapper struct {
*elf.File
}
func (f elfFileWrapper) Sections() []elf.SectionHeader {
ret := make([]elf.SectionHeader, len(f.
File.Sections))
for i, section := range f.
File.Sections {
ret[i] = section.SectionHeader
}
return ret
}
func (f elfFileWrapper)
Type() elf.
Type {
return f.
File.
Type
}
type mockElfFile struct {
symbols []elf.
Symbol
sections []elf.SectionHeader
t elf.
Type
}
func (f mockElfFile) Sections() []elf.SectionHeader { return f.sections }
func (f mockElfFile) Symbols() ([]elf.
Symbol, error) { return f.symbols, nil }
func (f mockElfFile)
Type() elf.
Type { return f.t }
func elfSymbolsFromFile(r io.ReaderAt) (
*File, error) {
elfFile, err := elf.NewFile(r)
if err != nil {
return nil, cantParseError{err}
}
return extractElfSymbols(elfFileWrapper{elfFile})
}
func extractElfSymbols(elfFile mockableElfFile) (
*File, error) {
symbols, err := elfFile.Symbols()
if err != nil {
return nil, err
}
file := &
File{}
for _, section := range elfFile.Sections() {
file.Sections =
append(
file.Sections, &Section{
Name: section.Name,
Addr: section.Addr,
Offset: section.Offset,
Size: section.
Size,
})
}
_ = elf.Section{}
for _,
symbol := range symbols {
if elf.ST_TYPE(
symbol.Info) != elf.STT_OBJECT {
continue
}
if symbol.Section == elf.SHN_UNDEF ||
symbol.Section >= elf.SHN_LORESERVE {
continue
}
if int(
symbol.Section) >= len(
file.Sections) {
return nil, fmt.Errorf(
"invalid section index %d",
symbol.Section)
}
section :=
file.Sections[
symbol.Section]
var addr uint64
switch elfFile.
Type() {
case elf.ET_REL:
//
"In relocatable files, st_value holds a section offset for a defined symbol.
// That
is, st_value
is an offset
from the beginning
of the section that st_shndx identifies.
"
addr =
symbol.Value
case elf.ET_EXEC, elf.ET_DYN:
//
"In executable and shared object files, st_value holds a virtual address. To make these
// files’ symbols more useful
for the dynamic linker, the section offset (
file interpretation)
// gives way
to a virtual address (
memory interpretation)
for which the section number
is
// irrelevant.
"
if symbol.Value < section.Addr {
return nil, fmt.Errorf(
"symbol starts before the start of its section")
}
addr =
symbol.Value - section.Addr
if addr+
symbol.
Size > section.
Size {
return nil, fmt.Errorf(
"symbol extends past the end of its section")
}
default:
return nil, fmt.Errorf(
"unsupported elf file type %d", elfFile.
Type())
}
file.Symbols =
append(
file.Symbols, &
Symbol{
Name:
symbol.Name,
Addr: addr,
Size:
symbol.
Size,
Section: section,
})
}
return
file, nil
}
func dumpElfSymbols(r io.ReaderAt) error {
elfFile, err := elf.NewFile(r)
if err != nil {
return cantParseError{err}
}
symbols, err := elfFile.Symbols()
if err != nil {
return err
}
fmt.Println(
"mockElfFile{")
fmt.Printf(
"\tt: %#v,\n", elfFile.
Type)
fmt.Println(
"\tsections: []elf.SectionHeader{")
for _, section := range elfFile.Sections {
fmt.Printf(
"\t\t%#v,\n", section.SectionHeader)
}
fmt.Println(
"\t},")
fmt.Println(
"\tsymbols: []elf.Symbol{")
for _,
symbol := range symbols {
fmt.Printf(
"\t\t%#v,\n",
symbol)
}
fmt.Println(
"\t},")
fmt.Println(
"}")
return nil
}