why does objcopy removes my section from binary? - embedded

I'm trying to link my tiny bare-metal educational project for ARM. I have one simple assembly source and linker script. There is a special separate section for exception vectors and startup code:
.section STARTUP_SECTION, "x"
_reset:
b reset_handler # Reset
b . # Undefined instruction
b . # SWI
b . # Prefetch Abort
b . # Data Abort
b . # reserved
b . # IRQ
b . # FIQ
reset_handler:
# some code here
b .
# then .text and .data section
And simple linker script:
ENTRY(_reset)
SECTIONS
{
. = 0;
.startup . :
{
startup.o (STARTUP_SECTION)
reset_section_end = .;
}
.text. : {*(.text)}
.data . : {*(.data)}
.bss . : {*(.bss COMMON)}
}
I see all my sections in map file produced by linker, and .text section lies at higher address than .startup as expected. But when I convert it to binary with:
arm-none-eabi-objcopy -O binary startup.elf startup.bin
...I see that it starts from .text contents, and my startup section is missing. I'm still able to see all sections in elf file when I disassemble it with objdump, but objcopy removes .startup. The section is not marked as NOLOAD or something like this. Is "NOLOAD" type a default for such section and why? And how to mark it as "LOAD" since there is no such section type according to linker manual.
What is going on here?

Related

Append text line after multiline match and stop on first multiline match

I would need a sed or awk command, not script, that:
1) matches in file sequentially 2 strings:
# This configuration option has an automatic default value.
# filter = [ "a|.*/|" ]
This is required because any single string can occur in file more than once.
But two of such sequential strings are pretty unique to match them.
2) inserts/appends after matched strings this text line:
filter = ["a|sd.*|", "a|drbd.*|", "r|.*|"]
3) stops processing after first match and append
So, text file looks like this:
...
# filter = [ "a|^/dev/hda8$|", "r|.*/|" ]
#
# This configuration option has an automatic default value.
# filter = [ "a|.*/|" ]
# Configuration option devices/global_filter.
# Limit the block devices that are used by LVM system components.
# Because devices/filter may be overridden from the command line, it is
# not suitable for system-wide device filtering, e.g. udev and lvmetad.
# Use global_filter to hide devices from these LVM system components.
# The syntax is the same as devices/filter. Devices rejected by
# global_filter are not opened by LVM.
# This configuration option has an automatic default value.
# global_filter = [ "a|.*/|" ]
# Configuration option devices/types.
# List of additional acceptable block device types.
# These are of device type names from /proc/devices, followed by the
...
I would need to have output like this:
...
# filter = [ "a|^/dev/hda8$|", "r|.*/|" ]
#
# This configuration option has an automatic default value.
# filter = [ "a|.*/|" ]
filter = ["a|sd.*|", "a|drbd.*|", "r|.*|"]
# Configuration option devices/global_filter.
# Limit the block devices that are used by LVM system components.
# Because devices/filter may be overridden from the command line, it is
# not suitable for system-wide device filtering, e.g. udev and lvmetad.
# Use global_filter to hide devices from these LVM system components.
# The syntax is the same as devices/filter. Devices rejected by
# global_filter are not opened by LVM.
# This configuration option has an automatic default value.
# global_filter = [ "a|.*/|" ]
# Configuration option devices/types.
# List of additional acceptable block device types.
# These are of device type names from /proc/devices, followed by the
...
None of found examples on multiline sed examples on stackoverflow is working for me.
I tried F. Hauri example from this topic: Append a string after a multiple line match in bash
sed -e $'/^admin:/,/^$/{/users:/a\ NewUser\n}'
It works fine, when matching unique words, but did not work for matching sequential text lines like this:
# This configuration option has an automatic default value.
# filter = [ "a|.*/|" ]
and also adding '0, to sed expression to stop on first match did not work in that case.
Updated description to better describe what is the goal.
awk '
/^\s+\# This configuration option has an automatic default value\./{
found=1
}
found && !flag && /\s+\# filter = \[ \"a\|\.\*\/\|\" \]/{
flag=1
$0=$0 ORS ORS " filter = [\"a|sd.*|\", \"a|drbd.*|\", \"r|.*|\"]"
}
1
' test.conf > test.tmp && cp test.conf test.conf.bak && mv -f test.tmp test.conf

How to resolve the issue "Can't find import Effects" in Idris?

I was trying to compile the following "hello world" source file after some time away from Idris using a nix-shell environment (direction):
module Main
import Effects
import Effect.StdIO
hello : Eff () [STDIO]
hello = putStrLn "Hello world!"
main : IO ()
main = run hello
My output was as follows during the experimentation; despite specifying what seems to be the right library, I still get the same error at the end:
[nix-shell:~/workspace/idris_tmp]$ idris --listlibs
00prelude-idx.ibc
prelude
00base-idx.ibc
base
[nix-shell:~/workspace/idris_tmp]$ exit
exit
brandon#brandon-750-170se-DevContainer:~/workspace/idris_tmp
$ nix-shell -p 'idrisPackages.with-packages (with idrisPackages; [ contrib effects ])' -p closurecompiler
these derivations will be built:
/nix/store/j44rkb0fpxqd4qkamrg1ysf9kbx1q2qa-idris-1.3.0.drv
these paths will be fetched (1.55 MiB download, 4.37 MiB unpacked):
/nix/store/1fcldlyp5n0ry22dsqfam68mpra6jky9-idris-effects-1.3.0
/nix/store/a9rjm84pbmvg6dmkdzhl9q1wliyi0q4b-idris-contrib-1.3.0
copying path '/nix/store/a9rjm84pbmvg6dmkdzhl9q1wliyi0q4b-idris-contrib-1.3.0' from 'https://cache.nixos.org'...
copying path '/nix/store/1fcldlyp5n0ry22dsqfam68mpra6jky9-idris-effects-1.3.0' from 'https://cache.nixos.org'...
building '/nix/store/j44rkb0fpxqd4qkamrg1ysf9kbx1q2qa-idris-1.3.0.drv'...
/nix/store/5dny6qnjfq9liya5z1sxvr2g64bqypwl-idris-base-1.3.0/nix-support:
propagated-build-inputs: /nix/store/1fcldlyp5n0ry22dsqfam68mpra6jky9-idris-effects-1.3.0/nix-support/propagated-build-inputs
/nix/store/a9rjm84pbmvg6dmkdzhl9q1wliyi0q4b-idris-contrib-1.3.0/nix-support:
propagated-build-inputs: /nix/store/1fcldlyp5n0ry22dsqfam68mpra6jky9-idris-effects-1.3.0/nix-support/propagated-build-inputs
/nix/store/a5x52wi84jgjiimpnkfpcl3mbpbkf1r4-idris-1.3.0/nix-support:
propagated-build-inputs: /nix/store/1fcldlyp5n0ry22dsqfam68mpra6jky9-idris-effects-1.3.0/nix-support/propagated-build-inputs
[nix-shell:~/workspace/idris_tmp]$ idris --listlibs
00effects-idx.ibc
effects
00base-idx.ibc
base
00prelude-idx.ibc
prelude
00contrib-idx.ibc
contrib
[nix-shell:~/workspace/idris_tmp]$ idris --codegen javascript hello.idr -o hello.js
Can't find import Effects
Try to add -p effects to your commandline as in
idris -p effects --codegen javascript hello.idr -o hello.js
this will load the additional library/package. You can avoid doing this by defining an ipkg file, which describes your build. See here: http://docs.idris-lang.org/en/latest/reference/packages.html

Perl 6 $*ARGFILES.handles in binary mode?

I'm trying out $*ARGFILES.handles and it seems that it opens the files in binary mode.
I'm writing a zip-merge program, that prints one line from each file until there are no more lines to read.
#! /usr/bin/env perl6
my #handles = $*ARGFILES.handles;
# say $_.encoding for #handles;
while #handles
{
my $handle = #handles.shift;
say $handle.get;
#handles.push($handle) unless $handle.eof;
}
I invoke it like this: zip-merge person-say3 repeat repeat2
It fails with: Cannot do 'get' on a handle in binary mode in block at ./zip-merge line 7
The specified files are text files (encoded in utf8), and I get the error message for non-executable files as well as executable ones (with perl6 code).
The commented out line says utf8 for every file I give it, so they should not be binary,
perl6 -v: This is Rakudo version 2018.10 built on MoarVM version 2018.10
Have I done something wrong, or have I uncovered an error?
The IO::Handle objects that .handles returns are closed.
my #*ARGS = 'test.p6';
my #handles = $*ARGFILES.handles;
for #handles { say $_ }
# IO::Handle<"test.p6".IO>(closed)
If you just want get your code to work, add the following line after assigning to #handles.
.open for #handles;
The reason for this is the iterator for .handles is written in terms of IO::CatHandle.next-handle which opens the current handle, and closes the previous handle.
The problem is that all of them get a chance to be both the current handle, and the previous handle before you get a chance to do any work on them.
(Perhaps .next-handle and/or .handles needs a :!close parameter.)
Assuming you want it to work like roundrobin I would actually write it more like this:
# /usr/bin/env perl6
use v6.d;
my #handles = $*ARGFILES.handles;
# a sequence of line sequences
my $line-seqs = #handles.map(*.open.lines);
# Seq.new(
# Seq.new( '# /usr/bin/env perl6', 'use v6.d' ), # first file
# Seq.new( 'foo', 'bar', 'baz' ), # second file
# )
for flat roundrobin $line-seqs {
.say
}
# `roundrobin` without `flat` would give the following result
# ('# /usr/bin/env perl6', 'foo'),
# ('use v6.d', 'bar'),
# ('baz')
If you used an array for $line-seqs, you will need to de-itemize (.<>) the values before passing them to roundrobin.
for flat roundrobin #line-seqs.map(*.<>) {
.say
}
Actually I personally would be more likely to write something similar to this (long) one-liner.
$*ARGFILES.handles.eagerĀ».openĀ».lines.&roundrobin.flat.map: *.put
:bin is always set in this type of objects. Since you are working on the handles, you should either read line by line as instructed on the example, or reset the handle so that it's not in binary mode.

Make all pages readable/writable/executable

I would like to grant full permissions (read, write, and execute) to all memory pages in an ELF binary. Ideally, I'd like to be able to do this as a transformation on a binary or object file, in the same way that symbols can be changed with objcopy. I have not yet found a good way to do this. I would also be okay with a solution that involves running code at startup that calls mprotect on every page with the flags PROT_READ | PROT_WRITE | PROT_EXEC. I've tried this briefly, but I haven't found a good way to know which pages are mapped, and therefore which pages need to be mprotected.
It isn't required that dynamically allocated pages have all permissions, only the pages mapped at program startup.
The following script implements Employed Russian's answer in code:
sets the p_type of the RELRO segment to PT_NULL
sets Flags on LOAD segments to PF_X|PF_W|PF_R.
It depends on pyelftools for python3, which can be installed with pip3 install pyelftools.
#!/usr/bin/env python3
import sys
from elftools.elf.elffile import ELFFile
from elftools.elf.descriptions import describe_p_type
if len(sys.argv) != 2:
print("Usage: elf_rwe <elf>")
name = sys.argv[1]
with open(name, "rb") as f:
elf = ELFFile(f)
rwe_offsets = []
relro_offsets = []
for i in range(elf['e_phnum']):
program_offset = elf['e_phoff'] + i * elf['e_phentsize']
f.seek(program_offset)
program_header = elf.structs.Elf_Phdr.parse_stream(f)
if program_header['p_type'] == "PT_LOAD":
rwe_offsets.append(program_offset)
if program_header['p_type'] == "PT_GNU_RELRO":
relro_offsets.append(program_offset)
f.seek(0)
b = list(f.read())
# Zap RELRO
pt_null = 0
for off in relro_offsets:
b[off] = pt_null
# Fix permissions
p_flags_offset = 4
for off in rwe_offsets:
b[off + p_flags_offset] = 0x7 # PF_X|PF_W|PF_R
with open(name, "wb") as f:
f.write(bytes(b))
I would like to grant full permissions (read, write, and execute) to all memory pages in an ELF binary.
Note that some security policies, such as W^X in selinux will prevent your binary from running.
Ideally, I'd like to be able to do this as a transformation on a binary or object file
Run readelf -Wl on your binary. You'll see something similar to:
$ readelf -Wl /bin/date
Elf file type is EXEC (Executable file)
Entry point 0x4021cf
There are 9 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000000000400040 0x0000000000400040 0x0001f8 0x0001f8 R E 0x8
INTERP 0x000238 0x0000000000400238 0x0000000000400238 0x00001c 0x00001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x00dde4 0x00dde4 R E 0x200000
LOAD 0x00de10 0x000000000060de10 0x000000000060de10 0x0004e4 0x0006b0 RW 0x200000
DYNAMIC 0x00de28 0x000000000060de28 0x000000000060de28 0x0001d0 0x0001d0 RW 0x8
NOTE 0x000254 0x0000000000400254 0x0000000000400254 0x000044 0x000044 R 0x4
GNU_EH_FRAME 0x00cb8c 0x000000000040cb8c 0x000000000040cb8c 0x0002f4 0x0002f4 R 0x4
GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x10
GNU_RELRO 0x00de10 0x000000000060de10 0x000000000060de10 0x0001f0 0x0001f0 R 0x1
What you want to do then is to change Flags on LOAD segments to have PF_X|PF_W|PF_R. The flags are part of Elf{32,64}_Phdr table, and the offset to the table is in stored in e_phoff of the Elf{32,64}_Ehdr (which is stored at the start of every ELF file).
Look in /usr/include/elf.h. Parsing fixed-sized ELF structures involved here isn't complicated.
You are unlikely to find any standard tool that would do this for you (given that this is such an unusual and unsecure thing to do), but a program to change flags is trivial to write in C, Python or Perl.
P.S. You may also need to "zap" the RELRO segment, which could be done by changing its p_type to PT_NULL.
I haven't found a good way to know which pages are mapped, and therefore which pages need to be mprotected.
On Linux, you could parse /proc/self/maps to get that info. Other OSes may offer a different way to achieve the same.

knitr 1.5 / patchDVI 1.9 doesn't seem to generate a concordance acceptable to evince + emacs

Setup : here is sessionInfo() :
R version 3.0.2 (2013-09-25)
Platform: x86_64-pc-linux-gnu (64-bit)
locale:
[1] LC_CTYPE=fr_FR.UTF-8 LC_NUMERIC=C
[3] LC_TIME=fr_FR.UTF-8 LC_COLLATE=fr_FR.UTF-8
[5] LC_MONETARY=fr_FR.UTF-8 LC_MESSAGES=fr_FR.UTF-8
[7] LC_PAPER=fr_FR.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=fr_FR.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] patchDVI_1.9 knitr_1.5
loaded via a namespace (and not attached):
[1] compiler_3.0.2 evaluate_0.5.1 formatR_0.9 highr_0.2.1 stringr_0.6.2
[6] tcltk_3.0.2 tools_3.0.2
I am trying to get emacs and AucTeX to synchronize my .Rnw source file with evince to go to comiled text from source and back.
I have already checked that the synchronization works fine between a .tex source and a PDF.
My .Rnw file starts with :
\documentclass[a4paper,twoside,12pt]{article}
\synctex=1 %% Should force concordance generation
\pdfcompresslevel=0 %% Should force avoidance of PDF compression, which patchDVI does
\pdfobjcompresslevel=0 %% not handle
<<include=FALSE>>= %% Modificaton of what Sweave2kinitr does
## opts_chunk$set(concordance=TRUE, self.contained=TRUE) ## No possible effect
opts_knit$set(concordance=TRUE, self.contained=TRUE) ## Seems reasonable
#
%% \SweaveOpts{concordance=TRUE} %% That's where inspiration came from
Consider the following log (unrelevant parts edited) :
> options("knitr.concordance")
$knitr.concordance
[1] TRUE
> opts_knit$get("concordance")
[1] TRUE
> knit("IntroStat.Rnw")
processing file: IntroStat.Rnw
|...................... | 33%
ordinary text without R code
|........................................... | 67%
label: unnamed-chunk-1 (with options)
List of 1
$ include: logi FALSE
|.................................................................| 100%
ordinary text without R code
output file: IntroStat.tex
[1] "IntroStat.tex"
> system("pdflatex -synctex=1 IntroStat.tex")
[ Edited irrelevancies ]
SyncTeX written on IntroStat.synctex.gz.
Note : a concordance has *been* generated !!! **
Transcript written on IntroStat.log.
Let's do that again to fix references :
> system("pdflatex -synctex=1 IntroStat.tex")
[ Edited irrelevancies ]
Output written on IntroStat.pdf (1 page, 136907 bytes).
SyncTeX written on IntroStat.synctex.gz.
Note : a concordance has *been* generated *again* !!! **
Transcript written on IntroStat.log.
> patchDVI("IntroStat.pdf")
[1] "0 patches made. Did you set \\SweaveOpts{concordance=TRUE}?"
* This I do not understand *
> patchSynctex("IntroStat.synctex.gz")
[1] "0 patches made. Did you set \\SweaveOpts{concordance=TRUE}?"
* Ditto *
It appears that something in the set of tools does not work as advertized : either dviPatch does not recognize legal concordance \specials or pdflatex dfoes not generate them. It does generate something, however...
I checked that the resulting PDF enables evince to synchronize with the .tex file, but not in the .Rnw file. Furthermore, when the .Rnw file is open in emacs, starting the viewer with 'C-c C-v View" in AucTeX indeed starts the viewer (after requesting to open a server, which I authorize), but the viewers is empty, and i get this :
"TeX-evince-sync-view: Couldn't find the Evince instance for file:///home/charpent/Boulot/Cours/ODF/Chapitres/Ch3-StatMath/IntroStat.Rnw.pdf"
in the "Messages" buffer.
So we have a second problem here.
A third one would be to integrate all of this transparently in the AucTeX production chain, but this is another story...
I'd really like to keep emacs as my main tool for R/\LaTeX/Sage work, rather tha switch to RStudio, which probably won't like much SageTeX and othe various tools I need on a daily/weekly basis...
Any thoughts ?
Maybe this https://github.com/jan-glx/patchKnitrSynctex will help. I tried it on a simple file, and it does work.
As for the second and third problems, I have this script (note that I source the above code from jan-glx; modify path accordingly):
#!/bin/bash
FILE=$1
BASENAME=$(basename $FILE .Rnw)
Rscript -e 'library(knitr); opts_knit$set("concordance" = TRUE); knit("'$1'")'
pdflatex --synctex=1 --file-line-error --shell-escape "${1%.*}"
Rscript -e "source('~/Sources/patchKnitrSynctex.R'); patchKnitrSynctex('${1%.*}.tex')"
ln -s $BASENAME.synctex.gz $BASENAME.Rnw.synctex.gz
ln -s $BASENAME.pdf $BASENAME.Rnw.pdf
The links are my kludgy way of getting around the "Couldn't find the instance (...) ".
If you have your .Rnw in an Emacs buffer, go to a shell buffer, and call that script. When finished, C-c C-v from Emacs will open your configured PDF viewer (okular in my case). In the PDF, shift + left mouse click (okular at least) will bring you to the right place in the Emacs .Rnw buffer.
This is not ideal: if you jump to an error, it goest to the .tex, not the .Rnw. And I'd like to be able to invoke it via C-c C-c or similar (but I don't know how ---elisp ignorance).