1*333d2b36SAndroid Build Coastguard Worker// Copyright 2022 Google Inc. All rights reserved. 2*333d2b36SAndroid Build Coastguard Worker// 3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*333d2b36SAndroid Build Coastguard Worker// 7*333d2b36SAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*333d2b36SAndroid Build Coastguard Worker// 9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*333d2b36SAndroid Build Coastguard Worker// limitations under the License. 14*333d2b36SAndroid Build Coastguard Worker 15*333d2b36SAndroid Build Coastguard Workerpackage elf 16*333d2b36SAndroid Build Coastguard Worker 17*333d2b36SAndroid Build Coastguard Workerimport ( 18*333d2b36SAndroid Build Coastguard Worker "bytes" 19*333d2b36SAndroid Build Coastguard Worker "debug/elf" 20*333d2b36SAndroid Build Coastguard Worker "encoding/binary" 21*333d2b36SAndroid Build Coastguard Worker "reflect" 22*333d2b36SAndroid Build Coastguard Worker "testing" 23*333d2b36SAndroid Build Coastguard Worker) 24*333d2b36SAndroid Build Coastguard Worker 25*333d2b36SAndroid Build Coastguard Workerfunc Test_elfIdentifierFromReaderAt_BadElfFile(t *testing.T) { 26*333d2b36SAndroid Build Coastguard Worker tests := []struct { 27*333d2b36SAndroid Build Coastguard Worker name string 28*333d2b36SAndroid Build Coastguard Worker contents string 29*333d2b36SAndroid Build Coastguard Worker }{ 30*333d2b36SAndroid Build Coastguard Worker { 31*333d2b36SAndroid Build Coastguard Worker name: "empty", 32*333d2b36SAndroid Build Coastguard Worker contents: "", 33*333d2b36SAndroid Build Coastguard Worker }, 34*333d2b36SAndroid Build Coastguard Worker { 35*333d2b36SAndroid Build Coastguard Worker name: "text", 36*333d2b36SAndroid Build Coastguard Worker contents: "#!/bin/bash\necho foobar", 37*333d2b36SAndroid Build Coastguard Worker }, 38*333d2b36SAndroid Build Coastguard Worker { 39*333d2b36SAndroid Build Coastguard Worker name: "empty elf", 40*333d2b36SAndroid Build Coastguard Worker contents: emptyElfFile(), 41*333d2b36SAndroid Build Coastguard Worker }, 42*333d2b36SAndroid Build Coastguard Worker { 43*333d2b36SAndroid Build Coastguard Worker name: "short section header", 44*333d2b36SAndroid Build Coastguard Worker contents: shortSectionHeaderElfFile(), 45*333d2b36SAndroid Build Coastguard Worker }, 46*333d2b36SAndroid Build Coastguard Worker } 47*333d2b36SAndroid Build Coastguard Worker 48*333d2b36SAndroid Build Coastguard Worker for _, tt := range tests { 49*333d2b36SAndroid Build Coastguard Worker t.Run(tt.name, func(t *testing.T) { 50*333d2b36SAndroid Build Coastguard Worker buf := bytes.NewReader([]byte(tt.contents)) 51*333d2b36SAndroid Build Coastguard Worker _, err := elfIdentifierFromReaderAt(buf, "<>", false) 52*333d2b36SAndroid Build Coastguard Worker if err == nil { 53*333d2b36SAndroid Build Coastguard Worker t.Errorf("expected error reading bad elf file without allowMissing") 54*333d2b36SAndroid Build Coastguard Worker } 55*333d2b36SAndroid Build Coastguard Worker _, err = elfIdentifierFromReaderAt(buf, "<>", true) 56*333d2b36SAndroid Build Coastguard Worker if err != nil { 57*333d2b36SAndroid Build Coastguard Worker t.Errorf("expected no error reading bad elf file with allowMissing, got %q", err.Error()) 58*333d2b36SAndroid Build Coastguard Worker } 59*333d2b36SAndroid Build Coastguard Worker }) 60*333d2b36SAndroid Build Coastguard Worker } 61*333d2b36SAndroid Build Coastguard Worker} 62*333d2b36SAndroid Build Coastguard Worker 63*333d2b36SAndroid Build Coastguard Workerfunc Test_readNote(t *testing.T) { 64*333d2b36SAndroid Build Coastguard Worker note := []byte{ 65*333d2b36SAndroid Build Coastguard Worker 0x04, 0x00, 0x00, 0x00, 66*333d2b36SAndroid Build Coastguard Worker 0x10, 0x00, 0x00, 0x00, 67*333d2b36SAndroid Build Coastguard Worker 0x03, 0x00, 0x00, 0x00, 68*333d2b36SAndroid Build Coastguard Worker 0x47, 0x4e, 0x55, 0x00, 69*333d2b36SAndroid Build Coastguard Worker 0xca, 0xaf, 0x44, 0xd2, 0x82, 0x78, 0x68, 0xfe, 0xc0, 0x90, 0xa3, 0x43, 0x85, 0x36, 0x6c, 0xc7, 70*333d2b36SAndroid Build Coastguard Worker } 71*333d2b36SAndroid Build Coastguard Worker 72*333d2b36SAndroid Build Coastguard Worker descs, err := readNote(bytes.NewBuffer(note), binary.LittleEndian) 73*333d2b36SAndroid Build Coastguard Worker if err != nil { 74*333d2b36SAndroid Build Coastguard Worker t.Fatalf("unexpected error in readNote: %s", err) 75*333d2b36SAndroid Build Coastguard Worker } 76*333d2b36SAndroid Build Coastguard Worker 77*333d2b36SAndroid Build Coastguard Worker expectedDescs := map[string][]byte{ 78*333d2b36SAndroid Build Coastguard Worker "GNU\x00": []byte{0xca, 0xaf, 0x44, 0xd2, 0x82, 0x78, 0x68, 0xfe, 0xc0, 0x90, 0xa3, 0x43, 0x85, 0x36, 0x6c, 0xc7}, 79*333d2b36SAndroid Build Coastguard Worker } 80*333d2b36SAndroid Build Coastguard Worker 81*333d2b36SAndroid Build Coastguard Worker if !reflect.DeepEqual(descs, expectedDescs) { 82*333d2b36SAndroid Build Coastguard Worker t.Errorf("incorrect return, want %#v got %#v", expectedDescs, descs) 83*333d2b36SAndroid Build Coastguard Worker } 84*333d2b36SAndroid Build Coastguard Worker} 85*333d2b36SAndroid Build Coastguard Worker 86*333d2b36SAndroid Build Coastguard Worker// emptyElfFile returns an elf file header with no program headers or sections. 87*333d2b36SAndroid Build Coastguard Workerfunc emptyElfFile() string { 88*333d2b36SAndroid Build Coastguard Worker ident := [elf.EI_NIDENT]byte{} 89*333d2b36SAndroid Build Coastguard Worker identBuf := bytes.NewBuffer(ident[0:0:elf.EI_NIDENT]) 90*333d2b36SAndroid Build Coastguard Worker binary.Write(identBuf, binary.LittleEndian, []byte("\x7fELF")) 91*333d2b36SAndroid Build Coastguard Worker binary.Write(identBuf, binary.LittleEndian, elf.ELFCLASS64) 92*333d2b36SAndroid Build Coastguard Worker binary.Write(identBuf, binary.LittleEndian, elf.ELFDATA2LSB) 93*333d2b36SAndroid Build Coastguard Worker binary.Write(identBuf, binary.LittleEndian, elf.EV_CURRENT) 94*333d2b36SAndroid Build Coastguard Worker binary.Write(identBuf, binary.LittleEndian, elf.ELFOSABI_LINUX) 95*333d2b36SAndroid Build Coastguard Worker binary.Write(identBuf, binary.LittleEndian, make([]byte, 8)) 96*333d2b36SAndroid Build Coastguard Worker 97*333d2b36SAndroid Build Coastguard Worker header := elf.Header64{ 98*333d2b36SAndroid Build Coastguard Worker Ident: ident, 99*333d2b36SAndroid Build Coastguard Worker Type: uint16(elf.ET_EXEC), 100*333d2b36SAndroid Build Coastguard Worker Machine: uint16(elf.EM_X86_64), 101*333d2b36SAndroid Build Coastguard Worker Version: uint32(elf.EV_CURRENT), 102*333d2b36SAndroid Build Coastguard Worker Entry: 0, 103*333d2b36SAndroid Build Coastguard Worker Phoff: uint64(binary.Size(elf.Header64{})), 104*333d2b36SAndroid Build Coastguard Worker Shoff: uint64(binary.Size(elf.Header64{})), 105*333d2b36SAndroid Build Coastguard Worker Flags: 0, 106*333d2b36SAndroid Build Coastguard Worker Ehsize: uint16(binary.Size(elf.Header64{})), 107*333d2b36SAndroid Build Coastguard Worker Phentsize: 0x38, 108*333d2b36SAndroid Build Coastguard Worker Phnum: 0, 109*333d2b36SAndroid Build Coastguard Worker Shentsize: 0x40, 110*333d2b36SAndroid Build Coastguard Worker Shnum: 0, 111*333d2b36SAndroid Build Coastguard Worker Shstrndx: 0, 112*333d2b36SAndroid Build Coastguard Worker } 113*333d2b36SAndroid Build Coastguard Worker 114*333d2b36SAndroid Build Coastguard Worker buf := &bytes.Buffer{} 115*333d2b36SAndroid Build Coastguard Worker binary.Write(buf, binary.LittleEndian, header) 116*333d2b36SAndroid Build Coastguard Worker return buf.String() 117*333d2b36SAndroid Build Coastguard Worker} 118*333d2b36SAndroid Build Coastguard Worker 119*333d2b36SAndroid Build Coastguard Worker// shortSectionHeader returns an elf file header with a section header that extends past the end of 120*333d2b36SAndroid Build Coastguard Worker// the file. 121*333d2b36SAndroid Build Coastguard Workerfunc shortSectionHeaderElfFile() string { 122*333d2b36SAndroid Build Coastguard Worker ident := [elf.EI_NIDENT]byte{} 123*333d2b36SAndroid Build Coastguard Worker identBuf := bytes.NewBuffer(ident[0:0:elf.EI_NIDENT]) 124*333d2b36SAndroid Build Coastguard Worker binary.Write(identBuf, binary.LittleEndian, []byte("\x7fELF")) 125*333d2b36SAndroid Build Coastguard Worker binary.Write(identBuf, binary.LittleEndian, elf.ELFCLASS64) 126*333d2b36SAndroid Build Coastguard Worker binary.Write(identBuf, binary.LittleEndian, elf.ELFDATA2LSB) 127*333d2b36SAndroid Build Coastguard Worker binary.Write(identBuf, binary.LittleEndian, elf.EV_CURRENT) 128*333d2b36SAndroid Build Coastguard Worker binary.Write(identBuf, binary.LittleEndian, elf.ELFOSABI_LINUX) 129*333d2b36SAndroid Build Coastguard Worker binary.Write(identBuf, binary.LittleEndian, make([]byte, 8)) 130*333d2b36SAndroid Build Coastguard Worker 131*333d2b36SAndroid Build Coastguard Worker header := elf.Header64{ 132*333d2b36SAndroid Build Coastguard Worker Ident: ident, 133*333d2b36SAndroid Build Coastguard Worker Type: uint16(elf.ET_EXEC), 134*333d2b36SAndroid Build Coastguard Worker Machine: uint16(elf.EM_X86_64), 135*333d2b36SAndroid Build Coastguard Worker Version: uint32(elf.EV_CURRENT), 136*333d2b36SAndroid Build Coastguard Worker Entry: 0, 137*333d2b36SAndroid Build Coastguard Worker Phoff: uint64(binary.Size(elf.Header64{})), 138*333d2b36SAndroid Build Coastguard Worker Shoff: uint64(binary.Size(elf.Header64{})), 139*333d2b36SAndroid Build Coastguard Worker Flags: 0, 140*333d2b36SAndroid Build Coastguard Worker Ehsize: uint16(binary.Size(elf.Header64{})), 141*333d2b36SAndroid Build Coastguard Worker Phentsize: 0x38, 142*333d2b36SAndroid Build Coastguard Worker Phnum: 0, 143*333d2b36SAndroid Build Coastguard Worker Shentsize: 0x40, 144*333d2b36SAndroid Build Coastguard Worker Shnum: 1, 145*333d2b36SAndroid Build Coastguard Worker Shstrndx: 0, 146*333d2b36SAndroid Build Coastguard Worker } 147*333d2b36SAndroid Build Coastguard Worker 148*333d2b36SAndroid Build Coastguard Worker buf := &bytes.Buffer{} 149*333d2b36SAndroid Build Coastguard Worker binary.Write(buf, binary.LittleEndian, header) 150*333d2b36SAndroid Build Coastguard Worker binary.Write(buf, binary.LittleEndian, []byte{0}) 151*333d2b36SAndroid Build Coastguard Worker return buf.String() 152*333d2b36SAndroid Build Coastguard Worker} 153