MCPcopy Index your code
hub / github.com/google/gvisor / Load

Method Load

pkg/sentry/arch/stack.go:139–222  ·  view source on GitHub ↗

Load pushes the given args, env and aux vector to the stack using the well-known format for a new executable. It returns the start and end of the argument and environment vectors.

(args []string, env []string, aux Auxv)

Source from the content-addressed store, hash-verified

137// well-known format for a new executable. It returns the start and end
138// of the argument and environment vectors.
139func (s *Stack) Load(args []string, env []string, aux Auxv) (StackLayout, error) {
140 l := StackLayout{}
141
142 // Make sure we start with a 16-byte alignment.
143 s.Align(16)
144
145 // Push the environment vector so the end of the argument vector is adjacent to
146 // the beginning of the environment vector.
147 // While the System V abi for x86_64 does not specify an ordering to the
148 // Information Block (the block holding the arg, env, and aux vectors),
149 // support features like setproctitle(3) naturally expect these segments
150 // to be in this order. See: https://www.uclibc.org/docs/psABI-x86_64.pdf
151 // page 29.
152 l.EnvvEnd = s.Bottom
153 envAddrs := make([]hostarch.Addr, len(env))
154 for i := len(env) - 1; i >= 0; i-- {
155 if _, err := s.PushNullTerminatedByteSlice([]byte(env[i])); err != nil {
156 return StackLayout{}, err
157 }
158 envAddrs[i] = s.Bottom
159 }
160 l.EnvvStart = s.Bottom
161
162 // Push our strings.
163 l.ArgvEnd = s.Bottom
164 argAddrs := make([]hostarch.Addr, len(args))
165 for i := len(args) - 1; i >= 0; i-- {
166 if _, err := s.PushNullTerminatedByteSlice([]byte(args[i])); err != nil {
167 return StackLayout{}, err
168 }
169 argAddrs[i] = s.Bottom
170 }
171 l.ArgvStart = s.Bottom
172
173 // We need to align the arguments appropriately.
174 //
175 // We must finish on a 16-byte alignment, but we'll play it
176 // conservatively and finish at 32-bytes. It would be nice to be able
177 // to call Align here, but unfortunately we need to align the stack
178 // with all the variable sized arrays pushed. So we just need to do
179 // some calculations.
180 argvSize := s.Arch.Width() * uint(len(args)+1)
181 envvSize := s.Arch.Width() * uint(len(env)+1)
182 auxvSize := s.Arch.Width() * 2 * uint(len(aux)+1)
183 total := hostarch.Addr(argvSize) + hostarch.Addr(envvSize) + hostarch.Addr(auxvSize) + hostarch.Addr(s.Arch.Width())
184 expectedBottom := s.Bottom - total
185 if expectedBottom%32 != 0 {
186 s.Bottom -= expectedBottom % 32
187 }
188
189 // Push our auxvec.
190 // NOTE: We need an extra zero here per spec.
191 // The Push function will automatically terminate
192 // strings and arrays with a single null value.
193 auxv := make([]hostarch.Addr, 0, len(aux)*2+1)
194 for _, a := range aux {
195 auxv = append(auxv, hostarch.Addr(a.Key), a.Value)
196 }

Callers

nothing calls this directly

Calls 7

AlignMethod · 0.95
AddrTypeAlias · 0.92
WidthMethod · 0.65
NativeMethod · 0.65
CopyOutMethod · 0.65

Tested by

no test coverage detected